ScaleSign API

Use the REST API to send documents for signature, create documents from templates, download signed PDFs and react to signing events. Everything you can do in the app is built on these same endpoints.

Base URL: https://sign.scalesmart.dev/api/v1

Requests and responses are JSON. Send Content-Type: application/json with request bodies.

IDs are UUIDs. Recipient and placeholder IDs inside a document are your own short references, such as "1" and "2".

Timestamps are ISO 8601 in UTC.

Quick start
curl "https://sign.scalesmart.dev/api/v1/me" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"

Authentication

Create API keys in Settings > API and send one with every request in the X-Api-Key header. Authorization: Bearer <key> works too. A key acts as the person who created it, inside that workspace, with their role. Keep keys secret: anyone with a key can send documents as you. Revoke a key any time and it stops working straight away.

Header
X-Api-Key: ss_9fK2m...

Test mode

Add X-TestMode-Enabled: true as a header, or "test_mode": true in the body when you create a document, to try things without using up your plan. Test documents are free, are clearly marked, are not legally binding and never count toward your document limits.

Rate limits

  • 100 requests a minute per workspace (20 a minute in test mode).
  • 30 a minute for creating documents and templates, and 10 a minute for bulk sends.

Over the limit you get 429 Too Many Requests with a body like { "error": "Too many requests, please try again shortly." }. Wait and retry.

Errors

Successful calls return 200, 201 or 204. Errors use standard HTTP status codes and a JSON body that explains what went wrong.

400
The request is malformed, for example invalid JSON.
401
The API key is missing, wrong or revoked.
402
Your plan doesn't include this, or you've hit a plan limit.
403
Your role can't do this.
404
Nothing with that ID in this workspace.
409
The document is in the wrong state for this change.
422
A parameter is missing or invalid.
429
Too many requests.
500
Something went wrong on our side.
422 Unprocessable Entity
{
  "message": "recipients.0.email: Invalid email",
  "errors": { "base": ["recipients.0.email: Invalid email"] },
  "meta": { "error": "unprocessable_entity", "message": "recipients.0.email: Invalid email", "messages": ["recipients.0.email: Invalid email"] }
}
404 Not Found
{ "message": "Document not found", "meta": { "error": "not_found", "message": "Document not found", "messages": ["Document not found"] } }

Pagination

List endpoints take page (from 1) and per_page (1 to 100, default 25; limit also works) and wrap results with paging details. Keep requesting while next_page is not null.

Paging fields
{ "documents": [...], "current_page": 2, "next_page": 3, "previous_page": 1, "total_count": 230, "total_pages": 10 }

Documents

A document is one or more files sent to recipients for signature. Create it as a draft to finish later, or send it straight away.

Create a document

POST/api/v1/documents

Uploads files, adds recipients and fields, and sends the document unless draft is true. Send JSON with files as file_url or file_base64, or multipart/form-data with files plus a JSON payload field. Fields are required unless the document is a draft, uses text_tags, or uses with_signature_page.

Body parameters

filesarrayRequired
Each item is { name, file_url } or { name, file_base64 }. PDF, Word, images and more are converted to PDF.
recipientsarrayRequired
Each item is { id, name, email, signing_order?, passcode?, passcode_delivery?, subject?, message?, send_email?, send_email_delay? }. id is your own reference, such as "1".
fieldsarray of arrays
One array per file. Each field has type, page, x, y, width, height, recipient_id and optional api_id, required, label, value, validation, date_format, options.
namestring
Document name. Defaults to the first file's name.
subject / messagestring
Email subject and message for recipients.
draftboolean
Save without sending. Send later with Update and send.
self_signboolean
Only the sender signs. No recipients needed.
test_modeboolean
Free, not legally binding and does not count toward limits. The X-TestMode-Enabled header works too.
apply_signing_orderboolean
Recipients sign one after another in signing_order.
expires_ininteger
Days until signing links expire (1 to 365).
remindersboolean
Send automatic reminders to recipients who haven't signed.
allow_decline / allow_reassignboolean
Let recipients decline, or pass the document to someone else.
redirect_url / decline_redirect_urlstring
Where to send recipients after they sign or decline.
embedded_signingboolean
Return embedded_signing_url for each recipient so you can sign inside your own app.
text_tagsboolean
Create fields from {{text tags}} found in the files.
copied_contactsarray
People to CC: [{ name, email }].
metadataobject
Your own key value pairs. Returned on every response and webhook.
labelsarray
Label names to file the document under.
languagestring
Recipient language code, such as en, fr, de or es.
checkbox_groups / conditional_rules / attachment_requestsarray
Checkbox validation groups, show or hide rules, and files to request from signers.
api_application_idstring
Brand and isolate the document with an API application.
Request
curl -X POST "https://sign.scalesmart.dev/api/v1/documents" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Services Agreement",
    "files": [{ "name": "agreement.pdf", "file_url": "https://example.com/agreement.pdf" }],
    "recipients": [{ "id": "1", "name": "Alex Kim", "email": "alex@example.com" }],
    "fields": [[{ "type": "signature", "page": 3, "x": 72, "y": 640, "width": 180, "height": 44, "recipient_id": "1", "api_id": "client_signature" }]],
    "metadata": { "deal_id": "4521" }
  }'
Response (201 Created)
{
  "id": "6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10",
  "object": "document",
  "name": "Services Agreement",
  "subject": "Please complete Services Agreement",
  "message": "Hi Alex, here is the agreement we discussed.",
  "status": "Sent",
  "test_mode": false,
  "draft": false,
  "requester_email_address": "jane@acme.com",
  "metadata": { "deal_id": "4521" },
  "created_at": "2026-10-20T09:14:02.884Z",
  "updated_at": "2026-10-20T09:14:03.120Z",
  "sent_at": "2026-10-20T09:14:03.120Z",
  "completed_at": null,
  "recipients": [
    {
      "id": "1",
      "uuid": "0f9a6c1e-6a52-4d0e-9a8e-3e1c1b2f4d77",
      "name": "Alex Kim",
      "email": "alex@example.com",
      "placeholder_name": null,
      "delivery_method": "email",
      "signing_order": 1,
      "signing_url": "https://sign.scalesmart.dev/sign/Xr8kq2mN4tY7",
      "embedded_signing_url": null,
      "bounced": false,
      "attachment_requests": [],
      "passcode": null,
      "passcode_delivery": { "enabled": false, "methods": null, "expire_after_access": false },
      "status": "sent",
      "sent_at": "2026-10-20T09:14:03.120Z",
      "viewed_at": null
    }
  ],
  "files": [{ "name": "agreement.pdf", "pages_number": 3 }],
  "fields": [
    [
      {
        "api_id": "client_signature",
        "type": "signature",
        "page": 3, "x": 72, "y": 640, "width": 180, "height": 44,
        "recipient_id": "1",
        "required": true,
        "value": null
      }
    ]
  ],
  "copied_contacts": [],
  "labels": [],
  "reminders": true,
  "apply_signing_order": false,
  "expires_in": 30,
  "expires_at": "2026-11-19T09:14:03.120Z",
  "allow_decline": true,
  "allow_reassign": true,
  "redirect_url": null,
  "language": "en",
  "embedded_signing": false,
  "embedded_edit_url": null,
  "embedded_preview_url": "https://sign.scalesmart.dev/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10?embedded=1",
  "checkbox_groups": [],
  "conditional_rules": [],
  "template_id": null,
  "template_ids": [],
  "completed_pdf_url": null
}

List documents

GET/api/v1/documents

Returns documents you can see, newest first. Members only see their own documents.

Query parameters

pageinteger
Page number, starting at 1.
per_pageinteger
Results per page, 1 to 100 (default 25). limit is accepted too.
statusstring
Comma separated: draft, sent, viewed, pending, completed, declined, expired, canceled, manually_completed.
searchstring
Matches document names and recipients.
personstring
Recipient name or email.
labelstring
Label name.
archivedboolean
true to list archived documents.
start_date / end_datedate
Created within this range (YYYY-MM-DD).
updated_after / updated_beforeISO 8601
Changed within this range.
viewstring
summary for a lighter object.
Request
curl -X GET "https://sign.scalesmart.dev/api/v1/documents?status=completed&per_page=10" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 OK)
{
  "documents": [ { "id": "6d0c3a9e-...", "name": "Services Agreement", "status": "Completed", ... } ],
  "current_page": 1,
  "next_page": 2,
  "previous_page": null,
  "total_count": 42,
  "total_pages": 2
}

Get a document

GET/api/v1/documents/{id}

Returns the document with its recipients, fields, field values and status.

Path parameters

idstring (uuid)Required
The document's ID.
Request
curl -X GET "https://sign.scalesmart.dev/api/v1/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 OK)
{
  "id": "6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10",
  "object": "document",
  "name": "Services Agreement",
  "subject": "Please complete Services Agreement",
  "message": "Hi Alex, here is the agreement we discussed.",
  "status": "Sent",
  "test_mode": false,
  "draft": false,
  "requester_email_address": "jane@acme.com",
  "metadata": { "deal_id": "4521" },
  "created_at": "2026-10-20T09:14:02.884Z",
  "updated_at": "2026-10-20T09:14:03.120Z",
  "sent_at": "2026-10-20T09:14:03.120Z",
  "completed_at": null,
  "recipients": [
    {
      "id": "1",
      "uuid": "0f9a6c1e-6a52-4d0e-9a8e-3e1c1b2f4d77",
      "name": "Alex Kim",
      "email": "alex@example.com",
      "placeholder_name": null,
      "delivery_method": "email",
      "signing_order": 1,
      "signing_url": "https://sign.scalesmart.dev/sign/Xr8kq2mN4tY7",
      "embedded_signing_url": null,
      "bounced": false,
      "attachment_requests": [],
      "passcode": null,
      "passcode_delivery": { "enabled": false, "methods": null, "expire_after_access": false },
      "status": "sent",
      "sent_at": "2026-10-20T09:14:03.120Z",
      "viewed_at": null
    }
  ],
  "files": [{ "name": "agreement.pdf", "pages_number": 3 }],
  "fields": [
    [
      {
        "api_id": "client_signature",
        "type": "signature",
        "page": 3, "x": 72, "y": 640, "width": 180, "height": 44,
        "recipient_id": "1",
        "required": true,
        "value": null
      }
    ]
  ],
  "copied_contacts": [],
  "labels": [],
  "reminders": true,
  "apply_signing_order": false,
  "expires_in": 30,
  "expires_at": "2026-11-19T09:14:03.120Z",
  "allow_decline": true,
  "allow_reassign": true,
  "redirect_url": null,
  "language": "en",
  "embedded_signing": false,
  "embedded_edit_url": null,
  "embedded_preview_url": "https://sign.scalesmart.dev/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10?embedded=1",
  "checkbox_groups": [],
  "conditional_rules": [],
  "template_id": null,
  "template_ids": [],
  "completed_pdf_url": null
}

Update a draft

PATCH/api/v1/documents/{id}

Changes a draft using the same fields as Create a document (except files). Also archives or unarchives any document with { "archived": true }.

Path parameters

idstring (uuid)Required
The document's ID.
Request
curl -X PATCH "https://sign.scalesmart.dev/api/v1/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Services Agreement v2", "expires_in": 14 }'
Response (200 OK)
{
  "id": "6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10",
  "object": "document",
  "name": "Services Agreement",
  "subject": "Please complete Services Agreement",
  "message": "Hi Alex, here is the agreement we discussed.",
  "status": "Sent",
  "test_mode": false,
  "draft": false,
  "requester_email_address": "jane@acme.com",
  "metadata": { "deal_id": "4521" },
  "created_at": "2026-10-20T09:14:02.884Z",
  "updated_at": "2026-10-20T09:14:03.120Z",
  "sent_at": "2026-10-20T09:14:03.120Z",
  "completed_at": null,
  "recipients": [
    {
      "id": "1",
      "uuid": "0f9a6c1e-6a52-4d0e-9a8e-3e1c1b2f4d77",
      "name": "Alex Kim",
      "email": "alex@example.com",
      "placeholder_name": null,
      "delivery_method": "email",
      "signing_order": 1,
      "signing_url": "https://sign.scalesmart.dev/sign/Xr8kq2mN4tY7",
      "embedded_signing_url": null,
      "bounced": false,
      "attachment_requests": [],
      "passcode": null,
      "passcode_delivery": { "enabled": false, "methods": null, "expire_after_access": false },
      "status": "sent",
      "sent_at": "2026-10-20T09:14:03.120Z",
      "viewed_at": null
    }
  ],
  "files": [{ "name": "agreement.pdf", "pages_number": 3 }],
  "fields": [
    [
      {
        "api_id": "client_signature",
        "type": "signature",
        "page": 3, "x": 72, "y": 640, "width": 180, "height": 44,
        "recipient_id": "1",
        "required": true,
        "value": null
      }
    ]
  ],
  "copied_contacts": [],
  "labels": [],
  "reminders": true,
  "apply_signing_order": false,
  "expires_in": 30,
  "expires_at": "2026-11-19T09:14:03.120Z",
  "allow_decline": true,
  "allow_reassign": true,
  "redirect_url": null,
  "language": "en",
  "embedded_signing": false,
  "embedded_edit_url": null,
  "embedded_preview_url": "https://sign.scalesmart.dev/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10?embedded=1",
  "checkbox_groups": [],
  "conditional_rules": [],
  "template_id": null,
  "template_ids": [],
  "completed_pdf_url": null
}

Delete a document

DELETE/api/v1/documents/{id}

Deletes the document. A document that is still out for signature is canceled first and recipients can no longer open it.

Path parameters

idstring (uuid)Required
The document's ID.
Request
curl -X DELETE "https://sign.scalesmart.dev/api/v1/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response: 204 No Content

Update and send

POST/api/v1/documents/{id}/send

Applies any changes in the body to a draft, then sends it to recipients.

Path parameters

idstring (uuid)Required
The document's ID.
Request
curl -X POST "https://sign.scalesmart.dev/api/v1/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10/send" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "subject": "Ready for your signature" }'
Response (200 OK)
{
  "id": "6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10",
  "object": "document",
  "name": "Services Agreement",
  "subject": "Please complete Services Agreement",
  "message": "Hi Alex, here is the agreement we discussed.",
  "status": "Sent",
  "test_mode": false,
  "draft": false,
  "requester_email_address": "jane@acme.com",
  "metadata": { "deal_id": "4521" },
  "created_at": "2026-10-20T09:14:02.884Z",
  "updated_at": "2026-10-20T09:14:03.120Z",
  "sent_at": "2026-10-20T09:14:03.120Z",
  "completed_at": null,
  "recipients": [
    {
      "id": "1",
      "uuid": "0f9a6c1e-6a52-4d0e-9a8e-3e1c1b2f4d77",
      "name": "Alex Kim",
      "email": "alex@example.com",
      "placeholder_name": null,
      "delivery_method": "email",
      "signing_order": 1,
      "signing_url": "https://sign.scalesmart.dev/sign/Xr8kq2mN4tY7",
      "embedded_signing_url": null,
      "bounced": false,
      "attachment_requests": [],
      "passcode": null,
      "passcode_delivery": { "enabled": false, "methods": null, "expire_after_access": false },
      "status": "sent",
      "sent_at": "2026-10-20T09:14:03.120Z",
      "viewed_at": null
    }
  ],
  "files": [{ "name": "agreement.pdf", "pages_number": 3 }],
  "fields": [
    [
      {
        "api_id": "client_signature",
        "type": "signature",
        "page": 3, "x": 72, "y": 640, "width": 180, "height": 44,
        "recipient_id": "1",
        "required": true,
        "value": null
      }
    ]
  ],
  "copied_contacts": [],
  "labels": [],
  "reminders": true,
  "apply_signing_order": false,
  "expires_in": 30,
  "expires_at": "2026-11-19T09:14:03.120Z",
  "allow_decline": true,
  "allow_reassign": true,
  "redirect_url": null,
  "language": "en",
  "embedded_signing": false,
  "embedded_edit_url": null,
  "embedded_preview_url": "https://sign.scalesmart.dev/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10?embedded=1",
  "checkbox_groups": [],
  "conditional_rules": [],
  "template_id": null,
  "template_ids": [],
  "completed_pdf_url": null
}

Update recipients

PATCH/api/v1/documents/{id}/recipients

Fixes the name, email, subject, message or passcode of recipients who haven't opened the document yet. Returns 409 for recipients who already started.

Path parameters

idstring (uuid)Required
The document's ID.

Body parameters

recipientsarrayRequired
[{ id, name?, email?, subject?, message?, passcode? }] where id is the recipient's id.
Request
curl -X PATCH "https://sign.scalesmart.dev/api/v1/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10/recipients" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "recipients": [{ "id": "1", "email": "alex.kim@example.com" }] }'
Response (200 OK)
{
  "id": "6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10",
  "object": "document",
  "name": "Services Agreement",
  "subject": "Please complete Services Agreement",
  "message": "Hi Alex, here is the agreement we discussed.",
  "status": "Sent",
  "test_mode": false,
  "draft": false,
  "requester_email_address": "jane@acme.com",
  "metadata": { "deal_id": "4521" },
  "created_at": "2026-10-20T09:14:02.884Z",
  "updated_at": "2026-10-20T09:14:03.120Z",
  "sent_at": "2026-10-20T09:14:03.120Z",
  "completed_at": null,
  "recipients": [
    {
      "id": "1",
      "uuid": "0f9a6c1e-6a52-4d0e-9a8e-3e1c1b2f4d77",
      "name": "Alex Kim",
      "email": "alex@example.com",
      "placeholder_name": null,
      "delivery_method": "email",
      "signing_order": 1,
      "signing_url": "https://sign.scalesmart.dev/sign/Xr8kq2mN4tY7",
      "embedded_signing_url": null,
      "bounced": false,
      "attachment_requests": [],
      "passcode": null,
      "passcode_delivery": { "enabled": false, "methods": null, "expire_after_access": false },
      "status": "sent",
      "sent_at": "2026-10-20T09:14:03.120Z",
      "viewed_at": null
    }
  ],
  "files": [{ "name": "agreement.pdf", "pages_number": 3 }],
  "fields": [
    [
      {
        "api_id": "client_signature",
        "type": "signature",
        "page": 3, "x": 72, "y": 640, "width": 180, "height": 44,
        "recipient_id": "1",
        "required": true,
        "value": null
      }
    ]
  ],
  "copied_contacts": [],
  "labels": [],
  "reminders": true,
  "apply_signing_order": false,
  "expires_in": 30,
  "expires_at": "2026-11-19T09:14:03.120Z",
  "allow_decline": true,
  "allow_reassign": true,
  "redirect_url": null,
  "language": "en",
  "embedded_signing": false,
  "embedded_edit_url": null,
  "embedded_preview_url": "https://sign.scalesmart.dev/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10?embedded=1",
  "checkbox_groups": [],
  "conditional_rules": [],
  "template_id": null,
  "template_ids": [],
  "completed_pdf_url": null
}

Update authentication

PATCH/api/v1/documents/{id}/authentication

Sets or removes a static passcode, or one-time email codes, for recipients who haven't started.

Path parameters

idstring (uuid)Required
The document's ID.

Body parameters

recipientsarrayRequired
[{ id, passcode?, passcode_delivery?: { enabled, methods: ["email"], expire_after_access } }]
Request
curl -X PATCH "https://sign.scalesmart.dev/api/v1/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10/authentication" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "recipients": [{ "id": "1", "passcode": "blue-harbor-42" }] }'
Response (200 OK)
{
  "id": "6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10",
  "object": "document",
  "name": "Services Agreement",
  "subject": "Please complete Services Agreement",
  "message": "Hi Alex, here is the agreement we discussed.",
  "status": "Sent",
  "test_mode": false,
  "draft": false,
  "requester_email_address": "jane@acme.com",
  "metadata": { "deal_id": "4521" },
  "created_at": "2026-10-20T09:14:02.884Z",
  "updated_at": "2026-10-20T09:14:03.120Z",
  "sent_at": "2026-10-20T09:14:03.120Z",
  "completed_at": null,
  "recipients": [
    {
      "id": "1",
      "uuid": "0f9a6c1e-6a52-4d0e-9a8e-3e1c1b2f4d77",
      "name": "Alex Kim",
      "email": "alex@example.com",
      "placeholder_name": null,
      "delivery_method": "email",
      "signing_order": 1,
      "signing_url": "https://sign.scalesmart.dev/sign/Xr8kq2mN4tY7",
      "embedded_signing_url": null,
      "bounced": false,
      "attachment_requests": [],
      "passcode": null,
      "passcode_delivery": { "enabled": false, "methods": null, "expire_after_access": false },
      "status": "sent",
      "sent_at": "2026-10-20T09:14:03.120Z",
      "viewed_at": null
    }
  ],
  "files": [{ "name": "agreement.pdf", "pages_number": 3 }],
  "fields": [
    [
      {
        "api_id": "client_signature",
        "type": "signature",
        "page": 3, "x": 72, "y": 640, "width": 180, "height": 44,
        "recipient_id": "1",
        "required": true,
        "value": null
      }
    ]
  ],
  "copied_contacts": [],
  "labels": [],
  "reminders": true,
  "apply_signing_order": false,
  "expires_in": 30,
  "expires_at": "2026-11-19T09:14:03.120Z",
  "allow_decline": true,
  "allow_reassign": true,
  "redirect_url": null,
  "language": "en",
  "embedded_signing": false,
  "embedded_edit_url": null,
  "embedded_preview_url": "https://sign.scalesmart.dev/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10?embedded=1",
  "checkbox_groups": [],
  "conditional_rules": [],
  "template_id": null,
  "template_ids": [],
  "completed_pdf_url": null
}

Send a reminder

POST/api/v1/documents/{id}/remind

Emails a reminder to everyone who still needs to sign, or only to the recipients you list.

Path parameters

idstring (uuid)Required
The document's ID.

Body parameters

recipientsarray
Optional. [{ id } or { email } or { name }] to remind only some recipients.
Request
curl -X POST "https://sign.scalesmart.dev/api/v1/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10/remind" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 OK)
{ "reminded": 1 }

Download the completed PDF

GET/api/v1/documents/{id}/completed_pdf

Returns the signed PDF with its audit report. Returns 400 until the document is complete and the final file is ready.

Path parameters

idstring (uuid)Required
The document's ID.

Query parameters

url_onlyboolean
true returns { file_url } instead of the file.
audit_pageboolean
false leaves out the audit report. Default true.
file_formatstring
pdf (default) or zip, which also includes any attachments.
Request
curl -X GET "https://sign.scalesmart.dev/api/v1/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10/completed_pdf" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -o signed.pdf
Response: 200 with application/pdf (or application/zip)

Templates

Templates hold reusable files and fields assigned to placeholders (roles like Client). Fill the placeholders with real people to create documents.

Create a template

POST/api/v1/document_templates

Same options as Create a document, with placeholders instead of recipients. Fields use placeholder_id. Set draft to false to make it available right away.

Body parameters

filesarrayRequired
As for documents.
placeholdersarrayRequired
[{ id, name, preassigned_recipient_name?, preassigned_recipient_email?, signing_order? }]
fieldsarray of arrays
Fields with placeholder_id instead of recipient_id.
copied_placeholdersarray
CC roles: [{ name, preassigned_recipient_name?, preassigned_recipient_email? }]
draftboolean
Leave as a draft to finish in the editor.
Request
curl -X POST "https://sign.scalesmart.dev/api/v1/document_templates" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Mutual NDA",
    "files": [{ "name": "nda.pdf", "file_url": "https://example.com/nda.pdf" }],
    "placeholders": [{ "id": "1", "name": "Client" }],
    "fields": [[{ "type": "text", "page": 1, "x": 90, "y": 210, "width": 200, "height": 24, "placeholder_id": "1", "api_id": "client_name" }]],
    "draft": false
  }'
Response (201 Created)
{
  "id": "b8e6f7a2-41d3-4c9a-8a8e-5d2f0f9c1e44",
  "object": "document_template",
  "name": "Mutual NDA",
  "subject": "Please sign the Mutual NDA",
  "message": null,
  "status": "Available",
  "placeholders": [
    { "id": "1", "name": "Client", "preassigned_recipient_name": null, "preassigned_recipient_email": null, "signing_order": 1 }
  ],
  "copied_placeholders": [],
  "files": [{ "name": "nda.pdf", "pages_number": 2 }],
  "fields": [[{ "api_id": "client_name", "type": "text", "page": 1, "x": 90, "y": 210, "width": 200, "height": 24, "recipient_id": "1", "required": true }]],
  "template_link": null,
  "created_at": "2026-10-18T15:02:11.000Z",
  "updated_at": "2026-10-18T15:09:47.000Z"
}

List templates

GET/api/v1/document_templates

Returns the workspace's templates.

Query parameters

pageinteger
Page number, starting at 1.
per_pageinteger
Results per page, 1 to 100 (default 25). limit is accepted too.
searchstring
Matches template names.
Request
curl -X GET "https://sign.scalesmart.dev/api/v1/document_templates" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 OK)
{
  "document_templates": [ { "id": "b8e6f7a2-...", "name": "Mutual NDA", ... } ],
  "current_page": 1,
  "next_page": 2,
  "previous_page": null,
  "total_count": 42,
  "total_pages": 2
}

Get a template

GET/api/v1/document_templates/{id}

Returns the template with its placeholders and fields.

Path parameters

idstring (uuid)Required
The template's ID.
Request
curl -X GET "https://sign.scalesmart.dev/api/v1/document_templates/b8e6f7a2-41d3-4c9a-8a8e-5d2f0f9c1e44" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 OK)
{
  "id": "b8e6f7a2-41d3-4c9a-8a8e-5d2f0f9c1e44",
  "object": "document_template",
  "name": "Mutual NDA",
  "subject": "Please sign the Mutual NDA",
  "message": null,
  "status": "Available",
  "placeholders": [
    { "id": "1", "name": "Client", "preassigned_recipient_name": null, "preassigned_recipient_email": null, "signing_order": 1 }
  ],
  "copied_placeholders": [],
  "files": [{ "name": "nda.pdf", "pages_number": 2 }],
  "fields": [[{ "api_id": "client_name", "type": "text", "page": 1, "x": 90, "y": 210, "width": 200, "height": 24, "recipient_id": "1", "required": true }]],
  "template_link": null,
  "created_at": "2026-10-18T15:02:11.000Z",
  "updated_at": "2026-10-18T15:09:47.000Z"
}

Update a template

PUT/api/v1/document_templates/{id}

Changes the template's settings, placeholders or fields. PATCH works the same way.

Path parameters

idstring (uuid)Required
The template's ID.
Request
curl -X PUT "https://sign.scalesmart.dev/api/v1/document_templates/b8e6f7a2-41d3-4c9a-8a8e-5d2f0f9c1e44" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "subject": "Please sign our NDA" }'
Response (200 OK)
{
  "id": "b8e6f7a2-41d3-4c9a-8a8e-5d2f0f9c1e44",
  "object": "document_template",
  "name": "Mutual NDA",
  "subject": "Please sign the Mutual NDA",
  "message": null,
  "status": "Available",
  "placeholders": [
    { "id": "1", "name": "Client", "preassigned_recipient_name": null, "preassigned_recipient_email": null, "signing_order": 1 }
  ],
  "copied_placeholders": [],
  "files": [{ "name": "nda.pdf", "pages_number": 2 }],
  "fields": [[{ "api_id": "client_name", "type": "text", "page": 1, "x": 90, "y": 210, "width": 200, "height": 24, "recipient_id": "1", "required": true }]],
  "template_link": null,
  "created_at": "2026-10-18T15:02:11.000Z",
  "updated_at": "2026-10-18T15:09:47.000Z"
}

Delete a template

DELETE/api/v1/document_templates/{id}

Deletes the template. Documents already created from it are not affected.

Path parameters

idstring (uuid)Required
The template's ID.
Request
curl -X DELETE "https://sign.scalesmart.dev/api/v1/document_templates/b8e6f7a2-41d3-4c9a-8a8e-5d2f0f9c1e44" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response: 204 No Content

Create a document from a template

POST/api/v1/document_templates/documents

Creates and sends a document from one or more templates. Match recipients to placeholders with placeholder_name and prefill fields by api_id.

Body parameters

template_id / template_idsstring / arrayRequired
One template, or several to combine into one document.
recipientsarrayRequired
[{ id, placeholder_name, name, email }]
template_fieldsarray
Prefill values: [{ api_id, value }]
exclude_placeholdersarray
Placeholder names to leave out.
draft / test_mode / metadata / labels / expires_in / remindersvarious
As for Create a document.
Request
curl -X POST "https://sign.scalesmart.dev/api/v1/document_templates/documents" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "b8e6f7a2-41d3-4c9a-8a8e-5d2f0f9c1e44",
    "recipients": [{ "id": "1", "placeholder_name": "Client", "name": "Alex Kim", "email": "alex@example.com" }],
    "template_fields": [{ "api_id": "client_name", "value": "Alex Kim" }]
  }'
Response (201 Created)
{
  "id": "6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10",
  "object": "document",
  "name": "Services Agreement",
  "subject": "Please complete Services Agreement",
  "message": "Hi Alex, here is the agreement we discussed.",
  "status": "Sent",
  "test_mode": false,
  "draft": false,
  "requester_email_address": "jane@acme.com",
  "metadata": { "deal_id": "4521" },
  "created_at": "2026-10-20T09:14:02.884Z",
  "updated_at": "2026-10-20T09:14:03.120Z",
  "sent_at": "2026-10-20T09:14:03.120Z",
  "completed_at": null,
  "recipients": [
    {
      "id": "1",
      "uuid": "0f9a6c1e-6a52-4d0e-9a8e-3e1c1b2f4d77",
      "name": "Alex Kim",
      "email": "alex@example.com",
      "placeholder_name": null,
      "delivery_method": "email",
      "signing_order": 1,
      "signing_url": "https://sign.scalesmart.dev/sign/Xr8kq2mN4tY7",
      "embedded_signing_url": null,
      "bounced": false,
      "attachment_requests": [],
      "passcode": null,
      "passcode_delivery": { "enabled": false, "methods": null, "expire_after_access": false },
      "status": "sent",
      "sent_at": "2026-10-20T09:14:03.120Z",
      "viewed_at": null
    }
  ],
  "files": [{ "name": "agreement.pdf", "pages_number": 3 }],
  "fields": [
    [
      {
        "api_id": "client_signature",
        "type": "signature",
        "page": 3, "x": 72, "y": 640, "width": 180, "height": 44,
        "recipient_id": "1",
        "required": true,
        "value": null
      }
    ]
  ],
  "copied_contacts": [],
  "labels": [],
  "reminders": true,
  "apply_signing_order": false,
  "expires_in": 30,
  "expires_at": "2026-11-19T09:14:03.120Z",
  "allow_decline": true,
  "allow_reassign": true,
  "redirect_url": null,
  "language": "en",
  "embedded_signing": false,
  "embedded_edit_url": null,
  "embedded_preview_url": "https://sign.scalesmart.dev/documents/6d0c3a9e-2c1f-4b8e-9f51-0c7c3f8e2a10?embedded=1",
  "checkbox_groups": [],
  "conditional_rules": [],
  "template_id": null,
  "template_ids": [],
  "completed_pdf_url": null
}

Bulk Send

Send the same template to many people at once from a CSV, one document per row.

Get the CSV template

GET/api/v1/bulk_sends/csv_template

Returns a CSV with a column for every placeholder and prefillable field of the templates.

Query parameters

template_idsstringRequired
Comma separated template IDs (template_ids[] also works).
base64boolean
true returns { bulk_send_csv } as base64 instead of a CSV file.
Request
curl -X GET "https://sign.scalesmart.dev/api/v1/bulk_sends/csv_template?template_ids=b8e6f7a2-41d3-4c9a-8a8e-5d2f0f9c1e44" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 with text/csv. Fill one row per document.)
client_name,client_email,client_client_name

Validate a CSV

POST/api/v1/bulk_sends/validate_csv

Checks a CSV before you send and returns any row errors.

Body parameters

template_idsarrayRequired
Template IDs.
bulk_send_csvstringRequired
Base64 encoded CSV, or the raw CSV text.
Request
curl -X POST "https://sign.scalesmart.dev/api/v1/bulk_sends/validate_csv" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "template_ids": ["b8e6f7a2-..."], "bulk_send_csv": "Q2xpZW50IE5hbWUs..." }'
Response (200 OK)
{ "valid": true, "rows": 120, "errors": [], "preview": [ ... ] }

Create a bulk send

POST/api/v1/bulk_sends

Creates one document per CSV row and sends them. Limited to 10 a minute.

Body parameters

template_idsarrayRequired
Template IDs.
bulk_send_csvstringRequired
Base64 encoded CSV, or the raw CSV text.
skip_row_errorsboolean
Send the valid rows even if some rows have errors.
name / subject / messagestring
Batch name and the email recipients get.
apply_signing_orderboolean
Sign in order within each document.
Request
curl -X POST "https://sign.scalesmart.dev/api/v1/bulk_sends" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "template_ids": ["b8e6f7a2-..."], "bulk_send_csv": "Q2xpZW50IE5hbWUs...", "name": "Q4 renewals" }'
Response (201 Created)
{
  "id": "e1d2c3b4-...",
  "name": "Q4 renewals",
  "status": "sent",
  "template_ids": ["b8e6f7a2-..."],
  "total_recipients": 120,
  "documents_count": 120,
  "completed_count": 0,
  "not_completed_count": 120,
  "errors": [],
  "archived": false,
  "sender": { "name": "Jane Cooper", "email": "jane@acme.com" },
  "created_at": "2026-10-20T10:00:00.000Z"
}

List bulk sends

GET/api/v1/bulk_sends

Returns bulk sends, newest first.

Query parameters

pageinteger
Page number, starting at 1.
per_pageinteger
Results per page, 1 to 100 (default 25). limit is accepted too.
user_emailstring
Only bulk sends by this sender.
archivedboolean
true for archived batches.
Request
curl -X GET "https://sign.scalesmart.dev/api/v1/bulk_sends" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 OK)
{
  "bulk_sends": [ { "id": "e1d2c3b4-...", "name": "Q4 renewals", ... } ],
  "current_page": 1,
  "next_page": 2,
  "previous_page": null,
  "total_count": 42,
  "total_pages": 2
}

Get a bulk send

GET/api/v1/bulk_sends/{id}

Returns the batch with its progress counts.

Path parameters

idstring (uuid)Required
The bulk send's ID.
Request
curl -X GET "https://sign.scalesmart.dev/api/v1/bulk_sends/e1d2c3b4-..." \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 OK)
{ "id": "e1d2c3b4-...", "name": "Q4 renewals", "completed_count": 87, ... }

List a bulk send's documents

GET/api/v1/bulk_sends/{id}/documents

Returns the documents in the batch.

Path parameters

idstring (uuid)Required
The bulk send's ID.

Query parameters

pageinteger
Page number, starting at 1.
per_pageinteger
Results per page, 1 to 100 (default 25). limit is accepted too.
statusstring
Comma separated statuses.
Request
curl -X GET "https://sign.scalesmart.dev/api/v1/bulk_sends/e1d2c3b4-.../documents?status=completed" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 OK)
{
  "documents": [ { "id": "...", "status": "Completed", ... } ],
  "current_page": 1,
  "next_page": 2,
  "previous_page": null,
  "total_count": 42,
  "total_pages": 2
}

Webhooks

Register URLs that receive events. See the Webhooks guide below for the payload and how to verify it.

List webhooks

GET/api/v1/hooks

Returns the workspace's webhooks with their latest deliveries.

Request
curl -X GET "https://sign.scalesmart.dev/api/v1/hooks" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 OK)
[
  {
    "id": "5a7e0c2b-9d31-4f6a-b1c8-2e4d6f8a0b13",
    "callback_url": "https://example.com/webhooks/scalesign",
    "api_application_id": null,
    "active": true,
    "created_at": "2026-10-01T08:00:00.000Z",
    "recent_deliveries": [
      { "id": "...", "event_type": "document_completed", "status": "delivered", "attempts": 1, "response_code": 200, "created_at": "2026-10-20T11:02:44.000Z" }
    ]
  }
]

Create a webhook

POST/api/v1/hooks

Starts sending events to callback_url. The returned id is also the key for verifying event hashes.

Body parameters

callback_urlstringRequired
An http or https URL.
api_application_idstring
Optional. Link the webhook to an API application.
Request
curl -X POST "https://sign.scalesmart.dev/api/v1/hooks" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "callback_url": "https://example.com/webhooks/scalesign" }'
Response (201 Created)
{ "id": "5a7e0c2b-9d31-4f6a-b1c8-2e4d6f8a0b13", "callback_url": "https://example.com/webhooks/scalesign", "api_application_id": null }

Delete a webhook

DELETE/api/v1/hooks/{id}

Stops sending events to the URL.

Path parameters

idstring (uuid)Required
The webhook's ID.
Request
curl -X DELETE "https://sign.scalesmart.dev/api/v1/hooks/5a7e0c2b-9d31-4f6a-b1c8-2e4d6f8a0b13" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response: 204 No Content

API Applications

API applications keep integrations apart and carry branding for embedded signing.

Create an API application

POST/api/v1/api_applications

Creates an application. Pass its id as api_application_id when you create documents.

Body parameters

namestringRequired
Display name.
callback_urlsarray
URLs used after embedded flows.
primary_color / button_text_color / link_colorstring
Hex colours such as #4f46e5.
button_border_radiusinteger
0 to 25 pixels.
Request
curl -X POST "https://sign.scalesmart.dev/api/v1/api_applications" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Customer portal", "primary_color": "#0f766e", "button_border_radius": 6 }'
Response (201 Created)
{ "id": "c4b3a291-...", "name": "Customer portal", "callback_urls": [], "primary_color": "#0f766e", "button_text_color": null, "link_color": null, "button_border_radius": 6, "created_at": "..." }

Get an API application

GET/api/v1/api_applications/{id}

Returns one application.

Path parameters

idstring (uuid)Required
The application's ID.
Request
curl -X GET "https://sign.scalesmart.dev/api/v1/api_applications/c4b3a291-..." \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 OK)
{ "id": "c4b3a291-...", "name": "Customer portal", "callback_urls": [], ... }

Delete an API application

DELETE/api/v1/api_applications/{id}

Deletes the application.

Path parameters

idstring (uuid)Required
The application's ID.
Request
curl -X DELETE "https://sign.scalesmart.dev/api/v1/api_applications/c4b3a291-..." \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response: 204 No Content

Account

Get credentials

GET/api/v1/me

Returns the user and workspace the API key belongs to. Handy for checking a key works.

Request
curl -X GET "https://sign.scalesmart.dev/api/v1/me" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 OK)
{
  "id": "6edc2d01-...:53c64142-...",
  "role": "owner",
  "user": { "id": "6edc2d01-...", "name": "Jane Cooper", "first_name": "Jane", "last_name": "Cooper", "email": "jane@acme.com", "preferences": { "time_zone": "UTC" } },
  "account": { "id": "53c64142-...", "name": "Acme Inc.", "plan_tier": "business", "active_templates": 4, "can_create_template": true, "active_users": [ ... ] },
  "workspace": { "...": "same as account" }
}

Get account

GET/api/v1/account

Returns the workspace's name, logo and preferences.

Request
curl -X GET "https://sign.scalesmart.dev/api/v1/account" \
  -H "X-Api-Key: $SCALESIGN_API_KEY"
Response (200 OK)
{
  "id": "53c64142-...",
  "name": "Acme Inc.",
  "logo_url": "https://sign.scalesmart.dev/api/public/logo/53c64142-...",
  "plan_tier": "business",
  "preferences": {
    "date_format": "MM/DD/YYYY",
    "days_until_links_expire": 30,
    "disable_apply_everywhere": false,
    "disable_drawn_signatures": false,
    "disable_typed_signatures": false,
    "disable_uploaded_signatures": false,
    "enable_redirect": false,
    "redirect_url": null,
    "hide_document_id_in_audit": false,
    "mute_branding": false,
    "separate_completed_file": false,
    "time_zone": "UTC",
    "recipient_language": "en",
    "digital_seal": true
  }
}

Update account

PUT/api/v1/account

Changes workspace settings. Needs an owner or admin key.

Body parameters

namestring
Workspace name.
time_zonestring
IANA zone for audit reports, such as Europe/London.
date_formatstring
MM/DD/YYYY, DD/MM/YYYY, YYYY/MM/DD, Month DD, YYYY or MM/DD/YYYY hh:mm:ss a.
recipient_languagestring
Language code.
days_until_links_expireinteger
1 to 365.
Request
curl -X PUT "https://sign.scalesmart.dev/api/v1/account" \
  -H "X-Api-Key: $SCALESIGN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "time_zone": "Asia/Dubai", "date_format": "DD/MM/YYYY" }'
Response (200 OK)
{ "id": "53c64142-...", "name": "Acme Inc.", "preferences": { "time_zone": "Asia/Dubai", "date_format": "DD/MM/YYYY", ... } }

Webhook events

Register a callback URL with Create a webhook or in Settings > API. ScaleSign sends a POST with a JSON body for every event in the workspace. Reply with any 2xx status within 10 seconds. Anything else is retried with exponential backoff (1, 2, 4, 8 minutes and so on) for up to 10 attempts. The same event can arrive more than once, so make your handler idempotent.

document_created
A document was created, as a draft or ready to send.
document_sent
A document was sent to its recipients.
document_viewed
A recipient opened the document. Fires on every view and includes related_signer.
document_in_progress
The first recipient started signing. Fires once per document.
document_recipients_updated
Recipient names, emails or passcodes were changed after sending.
document_signed
One recipient finished signing. Includes related_signer.
document_completed
Everyone has signed and the final PDF with its audit report is ready.
document_expired
The signing links expired before everyone signed.
document_canceled
The sender canceled the document.
document_declined
A recipient declined to sign. Includes related_signer and the reason.
document_bounced
An email to a recipient bounced.
document_error
Something went wrong while processing the document.
template_created
A template was created.
template_error
Something went wrong while processing a template.
Payload
{
  "event": {
    "type": "document_signed",
    "time": 1792486249,
    "hash": "4f0c1d8e9b...e27a",
    "related_signer": { "name": "Alex Kim", "email": "alex@example.com" }
  },
  "data": {
    "object": { "id": "6d0c3a9e-...", "object": "document", "status": "Pending", "...": "same as GET /documents/{id}" },
    "account_id": "53c64142-..."
  }
}

data.object is the full document (or template), the same as Get a document, including your metadata. related_signer is present on viewed, signed and declined events.

Verifying events

Each event carries a hash so you can confirm it came from ScaleSign. Compute an HMAC SHA-256 hex digest using the webhook's ID as the key and `${event.type}@${event.time}` as the message, then compare it with event.hash in constant time.

Formula
hash = HMAC_SHA256(key = webhook_id, message = event.type + "@" + event.time)   // lowercase hex
Node.js (Express)
import crypto from "node:crypto";
import express from "express";

const app = express();

// The webhook's ID (from POST /api/v1/hooks or Settings > API) is the signing key.
const WEBHOOK_ID = process.env.SCALESIGN_WEBHOOK_ID;

function isGenuine(event) {
  const expected = crypto
    .createHmac("sha256", WEBHOOK_ID)
    .update(`${event.type}@${event.time}`)
    .digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(String(event.hash));
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

app.post("/webhooks/scalesign", express.json({ limit: "5mb" }), (req, res) => {
  const { event, data } = req.body;
  if (!isGenuine(event)) return res.sendStatus(401);

  if (event.type === "document_completed") {
    console.log("Signed:", data.object.name, data.object.metadata);
  }
  res.sendStatus(200);
});

app.listen(3000);
Python (Flask)
import hashlib
import hmac
import os

from flask import Flask, abort, request

app = Flask(__name__)

# The webhook's ID (from POST /api/v1/hooks or Settings > API) is the signing key.
WEBHOOK_ID = os.environ["SCALESIGN_WEBHOOK_ID"]


def is_genuine(event: dict) -> bool:
    message = f"{event['type']}@{event['time']}".encode()
    expected = hmac.new(WEBHOOK_ID.encode(), message, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, str(event.get("hash", "")))


@app.post("/webhooks/scalesign")
def scalesign_webhook():
    body = request.get_json(force=True)
    if not is_genuine(body["event"]):
        abort(401)
    if body["event"]["type"] == "document_completed":
        print("Signed:", body["data"]["object"]["name"])
    return "", 200

Embedded signing

Let people sign inside your own website or app without leaving it.

  1. Create the document with "embedded_signing": true. Recipients are not emailed unless you set send_email on them, and each recipient in the response has an embedded_signing_url.
  2. Load https://sign.scalesmart.dev/embedded.js on your page and open the URL with new ScaleSignEmbed(...). Pass containerId to render it inside an element, or leave it out to show a modal.
  3. Listen for events to update your UI, and use webhooks for anything that must not be missed. Set embedded_signing_notifications if the sender and CC'd people should still get the completed email.
HTML
<div id="signing" style="height: 720px"></div>

<script src="https://sign.scalesmart.dev/embedded.js"></script>
<script>
  const embed = new ScaleSignEmbed({
    // embedded_signing_url from the recipient in the API response
    url: "https://sign.scalesmart.dev/sign/Xr8kq2mN4tY7?embedded=1",
    // Leave out containerId to open signing in a full screen modal instead
    containerId: "signing",
    events: {
      iframeLoaded: (e) => console.log("Loaded", e.id),
      documentLoaded: (e) => console.log("Ready to sign", e.id),
      completed: (e) => console.log("Signed", e.id, e.url),
      declined: (e) => console.log("Declined", e.id, e.declineReason),
      closed: (e) => console.log("Closed", e.id),
      error: (e) => console.error("Something went wrong", e),
    },
  });
  embed.open();
</script>
iframeLoaded{ id }
The signing frame has loaded.
documentLoaded{ id }
The document is ready to sign.
completed{ id, url? }
The signer finished. url downloads the completed PDF once everyone has signed.
declined{ id, declineReason }
The signer declined.
closed{ id }
The signer closed the frame.
error{ id?, message }
Something went wrong.

Prefer your own iframe? The signing page posts the same events to its parent window:

postMessage
window.addEventListener("message", (msg) => {
  if (msg.origin !== "https://sign.scalesmart.dev" || msg.data?.source !== "scalesign") return;
  const { event, data } = msg.data; // event: iframeLoaded | documentLoaded | completed | declined | closed | error
  if (event === "completed") showThankYou(data.id);
});

Text tags

Text tags let you place fields by typing them into your Word or PDF file instead of passing coordinates. Set "text_tags": true when you create a document or template and every {{...}} tag becomes a field the size of the tag text. Tags stay in the PDF, so make them white to hide them.

Syntax
{{type:signer:required:label:prefill:api_id:width:height}}
1 type
Field type or its short alias (below).
2 signer
Recipient number, starting at 1. Defaults to 1.
3 required
y or n. Fields are required unless you say n (checkboxes default to optional).
4 label
Label shown to the signer.
5 prefill
A starting value.
6 api_id
Your ID for reading the value back through the API.
7, 8 width, height
Size in points, if you don't want the tag's own size.
9, 10 text only
Validation (numbers, letters, email_address, us_phone_number, us_zip_code, us_age, alphanumeric) and fixed width (y or n).
9, 10, 11 date only
Lock to the signing date (y or n), format (mm/dd/yyyy, dd/mm/yyyy, yyyy/mm/dd, mm/dd/yyyy hh.mm.ss a) and a formula such as sent_date + 10 days.
Examples
{{s:1}}                              Signature for recipient 1
{{i:2}}                              Initials for recipient 2
{{t:1:y:Company name::company}}      Required text with api_id company
{{t:1:n:Zip code:::::us_zip_code}}   Optional text, validated as a zip code
{{d:1:y:Start date:::::y}}           Locked to the signing date
{{d:2:y:Due:::::n:dd/mm/yyyy:sent_date + 30 days}}
{{c:1:n:I agree to the terms}}       Optional checkbox
{{af_n:1}}  {{af_e:1}}               Name and email, filled in for the signer
Variables
{{set=age:t:1:y:Your age}}   defines and places a tag
{{age}}                      places the same tag again
TypeAliasField
signaturesSignature
initialiInitials
texttText box
datedDate picker
checkcCheckbox
autofill_nameaf_nSigner's full name
autofill_first_nameaf_f_nFirst name
autofill_last_nameaf_l_nLast name
autofill_emailaf_eEmail address
autofill_companyaf_cCompany
autofill_titleaf_tJob title
autofill_phoneaf_pPhone number
autofill_date_signedaf_d_sDate signed

Date formulas can use created_date, sent_date and signed_date with day(s), week(s) or month(s), plus and minus, and parentheses.