SignSecure Docs

API reference

The SignSecure API is organised around REST. It has predictable, resource-oriented URLs, takes JSON request bodies, returns JSON responses, and uses standard HTTP verbs, status codes and authentication.

The API covers the whole life of an envelope: create it, upload documents, choose who signs and where, send it, chase it, and find out the moment it is signed. People, billing and saved templates are managed in the app. The same rules apply either way: an API key cannot send more than the account's plan allows, and cannot see anything outside its own organisation.

New here? Start with the quickstart, which sends a real document for signature in five calls.

Base URL

https://www.signsecure.org/v1

The API is on the same host as the app, over HTTPS only. Plain HTTP requests are redirected, and a redirected request is not one you want to send your key in, so always use the address above.

Base URL
{
  "base_url": "https://www.signsecure.org/v1",
  "version": "v1",
  "format": "JSON"
}

Authentication

The API authenticates requests with your secret API key. Send it in the Authorization header as a bearer token. If you prefer HTTP Basic auth, use the key as the username and leave the password empty, which is what curl -u ss_live_...: does.

Keys start with ss_live_ and are 51 characters long. An admin creates them under Developers in the app. The full key is shown once, when it is made. Only a hash of it is stored, so if you lose it, revoke it and make another.

A key acts as the admin who created it, with the rights of a Creator: it can create, send and read envelopes, but it cannot manage people, roles or billing. If that person leaves the organisation, their keys stop working at once.

Your API key can send documents in your organisation's name. Keep it on your server, in a secret store or an environment variable. Never put it in a browser, a mobile app or a public repository.

Requests without a key, with a key that has been revoked, or with something that is not a key at all, fail with 401.

Plans

The API is included on the Business plan. A request from an account that is not on Business returns 402 with the code plan_required, and that is checked on every request, so cancelling a subscription stops the API with it.

Authenticated request
curl https://www.signsecure.org/v1/account \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"

Errors

SignSecure uses conventional HTTP status codes. Codes in the 2xx range mean success. Codes in the 4xx range mean the request failed because of what was sent, and the error says which part. Codes in the 5xx range mean something went wrong on our side.

Every error has the same shape. type is the broad category and is safe to branch on. code, when present, is a short machine-readable reason. message is written for a person and may change. param names the parameter at fault, using bracket notation for nested ones, such as recipients[1][email].

HTTP status codes

CodeMeaning
200OKEverything worked as expected.
400Bad RequestThe request was unacceptable, often because a parameter is missing, unknown or invalid.
401UnauthorizedNo valid API key was provided.
402Payment RequiredThe request needs something the plan does not include, or a plan limit has been reached.
403ForbiddenThe key is valid but its role cannot do this.
404Not FoundThe resource does not exist, or belongs to another organisation.
409ConflictThe envelope is in a state that does not allow this, such as editing one that has been sent.
413Payload Too LargeThe file or the request body is over the limit.
415Unsupported Media TypeThe uploaded file is not a type SignSecure can read.
429Too Many RequestsToo many requests too quickly. Back off and retry.
500, 503Server errorsSomething went wrong on our side. These are rare.

Error types

TypeDescription
invalid_request_errorThe request has a problem: a parameter, a missing resource, or an envelope in the wrong state.
authentication_errorThe API key is missing, invalid or revoked, or its owner has left the organisation.
permission_errorThe key is valid but its role does not allow the action.
billing_errorThe plan does not include this, or a plan limit has been reached.
idempotency_errorAn Idempotency-Key was reused with a different request, or is still in use.
rate_limit_errorToo many requests. The response includes a Retry-After header when we know how long to wait.
api_errorAnything else. Quote the request_id if you contact support.

Attributes

  • typestring

    The category of error. One of the types above.

  • codenullable string

    A short, stable reason, such as parameter_missing, resource_missing or invalid_state.

  • messagestring

    A human-readable explanation. Show it to a developer, not to an end user.

  • paramnullable string

    The parameter the error relates to, if any.

  • request_idstring

    The id of this request, also sent as the Request-Id header.

Error response
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "Missing required parameter: fields.",
    "param": "fields",
    "request_id": "req_0d2f4b6a8c1e3a5b7d9f0c"
  }
}

Idempotent requests

Networks fail. A request can time out after the server has acted on it, and retrying a "create envelope" or a "send" blindly can do it twice. Idempotency keys make a retry safe.

Send an Idempotency-Key header with any POST. The first request runs normally and SignSecure remembers what it produced for 24 hours. A retry with the same key does not run again: it gets the same envelope, document or endpoint back, as it is now, with the header Idempotent-Replayed: true. An error is replayed exactly as it was first returned.

Use a value that is unique to the operation, such as a UUID, or your own record id plus what you are doing with it. Reusing a key with a different method, path or body is an idempotency_error, because that is almost always a bug. If the first request is still running, a retry gets 409 and should wait a moment.

Responses with a 5xx or 429 status are not remembered, so retrying with the same key runs the request again. A request that never finished frees its key after a minute. A webhook endpoint's signing secret is never replayed; it is only in the first response. GET, PUT and DELETE requests are idempotent already and ignore the header.

Idempotent request
curl https://www.signsecure.org/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b/send \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -H "Idempotency-Key: 006Qy00000AbCdE-send" \
  -X POST

Metadata

Envelopes have a metadata parameter for your own key-value pairs. It is how an integration finds its way back from an envelope to the record it came from: put your CRM record id in it when you create the envelope, and it arrives in every webhook about that envelope.

Metadata can be up to 20 keys. Keys are up to 40 characters, and values are strings of up to 500 characters. Updating metadata merges with what is there; set a key to an empty string to remove it. Unlike the rest of an envelope, metadata can be changed after it has been sent, because it is your bookkeeping and not part of what anyone signs.

SignSecure does not read metadata or show it to recipients. Do not put anything sensitive in it, such as bank details or passwords.

Metadata on an envelope
{
  "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
  "object": "envelope",
  "metadata": {
    "crm_record": "006Qy00000AbCdE",
    "deal_stage": "contract"
  },
  "…": "…"
}

Pagination

List endpoints return results newest first, a page at a time. Every list has the same shape: data holds the page, and has_more says whether there is another.

To get the next page, pass the id of the last item you received as starting_after. The cursor is an id rather than a page number, so nothing is skipped or repeated if new envelopes arrive while you are paging.

Parameters

  • limitintegeroptional

    How many objects to return, from 1 to 100. Defaults to 10.

  • starting_afterstringoptional

    A cursor for pagination: the id of the last object on the previous page. For example, if your last call ended with env_foo, pass starting_after=env_foo to get the page after it.

List object

  • objectstring

    Always list.

  • dataarray

    The objects on this page.

  • has_moreboolean

    Whether there are more objects after this page.

  • urlstring

    The path this list came from.

A list
{
  "object": "list",
  "url": "/v1/envelopes",
  "has_more": true,
  "data": [
    "{ …envelope… }",
    "{ …envelope… }"
  ]
}

Request IDs

Every response, success or error, has a Request-Id header, and every error body repeats it as request_id. If you need to ask us about a request, quote its id and we can find exactly what happened.

Response headers
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Request-Id: req_0d2f4b6a8c1e3a5b7d9f0c

Envelope allowance

Business includes an allowance of envelopes, shared across the account: 100 per seat a year on yearly billing, or 10 per seat a month on monthly. The free plan includes 5 a month.

An envelope counts once, when it is sent, however many documents and signers are in it. Drafts are free, and voiding a sent envelope does not give it back.

Past the allowance, sending on Business never stops. Each extra envelope is £2.00, added to the next invoice and billed monthly in arrears, and the envelope's audit trail records it. On the free plan, a send past the allowance fails with 402 and the code plan_limit.

The account shows how much of the allowance is used, so an integration can warn someone before they go over.

Rate limits

Limits keep one integration from crowding out everyone else, and stop a leaked key from doing much before you notice it. A request over a limit fails with 429 and the type rate_limit_error. Wait, then retry with exponential backoff.

Every signing email goes out from SignSecure's own domain, so the email limit counts emails, not envelopes: a parallel envelope to 20 people spends 20.

If a limit gets in the way of something legitimate, email support and tell us what you are building.

LimitValue
Requests300 a minute per account, across all its keys.
Uploads30 documents a minute per account, each up to 8 MB.
Sending500 envelopes an hour per account through the API.
Signing emails1,000 an hour per account, counting every email a send, a reminder or a correction causes, from the app or the API.
RemindersOne reminder an hour per envelope through the API.
CorrectionsThree a day per recipient.
Recipients50 per envelope.
Fields500 per envelope.
Request bodies1 MB of JSON, or 12 MB for a base64 document upload.
Webhook endpoints10 per account.
API keys20 per account.

Plan limits still apply through the API. The identity check add-on is metered per signer, and sending an envelope that asks for more identity checks than the account has left fails with 402.

Envelopes

An envelope is one request for signatures: the documents, the people who need to sign them, and where each person signs. You build it as a draft, send it, and it moves through its statuses until everyone has signed or it is stopped.

A draft can be changed freely. Once an envelope is sent, its documents, recipients and fields are fixed: they are what the signers are agreeing to.

The envelope object

Attributes

  • idstring

    Unique identifier for the envelope.

  • objectstring

    Always envelope.

  • statusenum

    Where the envelope is in its life.

    draft Being prepared. Nothing has been sent.
    sent Out for signature.
    completed Everyone has signed. The signed PDF is ready.
    declined A signer declined, so nobody else is asked to sign.
    voided You withdrew it. Outstanding links stopped working.
    expired The signing links ran out before everyone signed.
  • subjectstring

    What the envelope is. Recipients see it as the email subject.

  • messagenullable string

    A note to recipients, shown in the email and above the document.

  • routing_modeenum

    The order people are asked to sign in.

    sequential One routing order at a time. Each person is emailed when it is their turn.
    parallel Every signer is emailed at once.
  • sender_emailnullable string

    The person the envelope is sent as. For an API key, the admin who created it.

  • created_viaenum

    api or app.

  • metadataobject

    Your key-value pairs. See Metadata.

  • createdtimestamp

    When the envelope was created, in Unix seconds.

  • sent_atnullable timestamp

    When it was sent.

  • completed_atnullable timestamp

    When the last signer finished.

  • expires_atnullable timestamp

    When the signing links stop working.

  • voided_atnullable timestamp

    When it was voided.

  • void_reasonnullable string

    The reason given when it was voided.

  • documentsarray of documents

    The documents, in the order they were uploaded.

  • recipientsarray of recipients

    The recipients, in routing order.

  • fieldsnullable array of fields

    The fields placed on the documents. null in lists and in events; retrieve the envelope to get them.

The envelope object
{
  "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
  "object": "envelope",
  "status": "draft",
  "subject": "Order form, Northwind Traders",
  "message": "Please sign by Friday.",
  "routing_mode": "sequential",
  "sender_email": "sales@yourcompany.com",
  "created_via": "api",
  "metadata": {
    "crm_record": "006Qy00000AbCdE"
  },
  "created": 1791576000,
  "sent_at": null,
  "completed_at": null,
  "expires_at": null,
  "voided_at": null,
  "void_reason": null,
  "documents": [
    {
      "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "object": "document",
      "name": "order-form.pdf",
      "page_count": 3,
      "size": 184320,
      "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
      "signed_sha256": null,
      "converted_from": null,
      "created": 1791576060
    }
  ],
  "recipients": [
    {
      "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "object": "recipient",
      "name": "Amara Okafor",
      "email": "amara.okafor@example.com",
      "role": "signer",
      "routing_order": 1,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    },
    {
      "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "object": "recipient",
      "name": "Ben Hughes",
      "email": "ben.hughes@example.com",
      "role": "signer",
      "routing_order": 2,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    }
  ],
  "fields": [
    {
      "id": "fld_5a1c3e7b9d2f4a6c8e0b1d",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.78,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_9e3b5d7f1a2c4e6b8d0f3a",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "date",
      "page_index": 2,
      "x": 0.5,
      "y": 0.79,
      "width": 0.2,
      "height": 0.04,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_0c4e6a8b2d1f3b5c7e9a4f",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.88,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    }
  ]
}

Create an envelope

Creates a draft envelope. You can add the recipients in the same call, then upload documents and place fields before you send it.

POST/v1/envelopes

Parameters

  • subjectstringoptional

    What the envelope is, up to 240 characters. Recipients see it as the email subject.

    Defaults to Untitled envelope, which is replaced by the first document's file name when you upload one.

  • messagestringoptional

    A note to recipients, up to 4,000 characters.

  • routing_modeenumoptional

    The order people are asked to sign in. Defaults to sequential.

    sequential One routing order at a time.
    parallel Every signer at once.
  • metadataobjectoptional

    Your key-value pairs. See Metadata.

  • recipientsarrayoptional

    The people on the envelope. The same as setting recipients afterwards. If any recipient is invalid, nothing is created.

    Child parameters
    • namestringRequired

      Their full name, up to 160 characters.

    • emailstringRequired

      Their email address. Each address can appear once per envelope.

    • roleenumoptional

      Defaults to signer.

      signer Signs. Needs at least one field before the envelope can be sent.
      copy Signs nothing, and gets the completed document when everyone has signed.
    • routing_orderintegeroptional

      When they sign under sequential routing, from 1 to 999. People with the same number are asked together. Defaults to their position in the list.

    • identity_requiredbooleanoptional

      Ask this signer to prove who they are with a photo ID before signing. Uses one identity check from the account's allowance when the envelope is sent. Signers only.

Returns

Returns the envelope object, with status set to draft.

POST/v1/envelopes
curl https://www.signsecure.org/v1/v1/envelopes \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Order form, Northwind Traders",
    "message": "Please sign by Friday.",
    "metadata": {
      "crm_record": "006Qy00000AbCdE"
    },
    "recipients": [
      {
        "name": "Amara Okafor",
        "email": "amara.okafor@example.com"
      },
      {
        "name": "Ben Hughes",
        "email": "ben.hughes@example.com",
        "routing_order": 2
      }
    ]
  }'
Response
{
  "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
  "object": "envelope",
  "status": "draft",
  "subject": "Order form, Northwind Traders",
  "message": "Please sign by Friday.",
  "routing_mode": "sequential",
  "sender_email": "sales@yourcompany.com",
  "created_via": "api",
  "metadata": {
    "crm_record": "006Qy00000AbCdE"
  },
  "created": 1791576000,
  "sent_at": null,
  "completed_at": null,
  "expires_at": null,
  "voided_at": null,
  "void_reason": null,
  "documents": [],
  "recipients": [
    {
      "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "object": "recipient",
      "name": "Amara Okafor",
      "email": "amara.okafor@example.com",
      "role": "signer",
      "routing_order": 1,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    },
    {
      "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "object": "recipient",
      "name": "Ben Hughes",
      "email": "ben.hughes@example.com",
      "role": "signer",
      "routing_order": 2,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    }
  ],
  "fields": []
}

Retrieve an envelope

Retrieves an envelope, with its documents, recipients and fields.

GET/v1/envelopes/:id

Parameters

No parameters.

Returns

Returns the envelope object if the id is valid. Returns 404 if it is not, including when the envelope belongs to another organisation.

GET/v1/envelopes/:id
curl https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"
Response
{
  "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
  "object": "envelope",
  "status": "sent",
  "subject": "Order form, Northwind Traders",
  "message": "Please sign by Friday.",
  "routing_mode": "sequential",
  "sender_email": "sales@yourcompany.com",
  "created_via": "api",
  "metadata": {
    "crm_record": "006Qy00000AbCdE"
  },
  "created": 1791576000,
  "sent_at": 1791576300,
  "completed_at": null,
  "expires_at": 1792785900,
  "voided_at": null,
  "void_reason": null,
  "documents": [
    {
      "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "object": "document",
      "name": "order-form.pdf",
      "page_count": 3,
      "size": 184320,
      "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
      "signed_sha256": null,
      "converted_from": null,
      "created": 1791576060
    }
  ],
  "recipients": [
    {
      "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "object": "recipient",
      "name": "Amara Okafor",
      "email": "amara.okafor@example.com",
      "role": "signer",
      "routing_order": 1,
      "status": "sent",
      "identity_required": false,
      "identity_status": null,
      "sent_at": 1791576300,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    },
    {
      "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "object": "recipient",
      "name": "Ben Hughes",
      "email": "ben.hughes@example.com",
      "role": "signer",
      "routing_order": 2,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    }
  ],
  "fields": [
    {
      "id": "fld_5a1c3e7b9d2f4a6c8e0b1d",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.78,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_9e3b5d7f1a2c4e6b8d0f3a",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "date",
      "page_index": 2,
      "x": 0.5,
      "y": 0.79,
      "width": 0.2,
      "height": 0.04,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_0c4e6a8b2d1f3b5c7e9a4f",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.88,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    }
  ]
}

Update an envelope

Updates an envelope. Parameters you leave out are unchanged.

subject, message and routing_mode can only be changed while the envelope is a draft. metadata can be changed at any time.

POST/v1/envelopes/:id

Parameters

  • subjectstringoptional

    Up to 240 characters. Cannot be empty.

  • messagestringoptional

    Up to 4,000 characters. An empty string removes it.

  • routing_modeenumoptional

    sequential or parallel.

  • metadataobjectoptional

    Merged with the existing metadata. Set a key to an empty string to remove it.

Returns

Returns the updated envelope object. Returns 409 with the code invalid_state if you change anything but metadata on an envelope that has been sent.

POST/v1/envelopes/:id
curl https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metadata": {
      "deal_stage": "contract"
    }
  }'
Response
{
  "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
  "object": "envelope",
  "status": "sent",
  "subject": "Order form, Northwind Traders",
  "message": "Please sign by Friday.",
  "routing_mode": "sequential",
  "sender_email": "sales@yourcompany.com",
  "created_via": "api",
  "metadata": {
    "crm_record": "006Qy00000AbCdE",
    "deal_stage": "contract"
  },
  "created": 1791576000,
  "sent_at": 1791576300,
  "completed_at": null,
  "expires_at": 1792785900,
  "voided_at": null,
  "void_reason": null,
  "documents": [
    {
      "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "object": "document",
      "name": "order-form.pdf",
      "page_count": 3,
      "size": 184320,
      "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
      "signed_sha256": null,
      "converted_from": null,
      "created": 1791576060
    }
  ],
  "recipients": [
    {
      "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "object": "recipient",
      "name": "Amara Okafor",
      "email": "amara.okafor@example.com",
      "role": "signer",
      "routing_order": 1,
      "status": "sent",
      "identity_required": false,
      "identity_status": null,
      "sent_at": 1791576300,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    },
    {
      "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "object": "recipient",
      "name": "Ben Hughes",
      "email": "ben.hughes@example.com",
      "role": "signer",
      "routing_order": 2,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    }
  ],
  "fields": [
    {
      "id": "fld_5a1c3e7b9d2f4a6c8e0b1d",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.78,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_9e3b5d7f1a2c4e6b8d0f3a",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "date",
      "page_index": 2,
      "x": 0.5,
      "y": 0.79,
      "width": 0.2,
      "height": 0.04,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_0c4e6a8b2d1f3b5c7e9a4f",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.88,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    }
  ]
}

List all envelopes

Returns your organisation's envelopes, newest first. Each one includes its documents and recipients. fields is null in lists, because an envelope can have thousands; retrieve the envelope to get them.

GET/v1/envelopes

Parameters

  • statusenumoptional

    Only envelopes with this status: draft, sent, completed, declined, voided or expired.

  • limitintegeroptional

    From 1 to 100. Defaults to 10.

  • starting_afterstringoptional

    A cursor for pagination.

Returns

A list object whose data holds up to limit envelopes. If there are none, data is empty.

GET/v1/envelopes
curl https://www.signsecure.org/v1/v1/envelopes?status=sent&limit=3
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"
Response
{
  "object": "list",
  "url": "/v1/envelopes",
  "has_more": false,
  "data": [
    {
      "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
      "object": "envelope",
      "status": "sent",
      "subject": "Order form, Northwind Traders",
      "message": "Please sign by Friday.",
      "routing_mode": "sequential",
      "sender_email": "sales@yourcompany.com",
      "created_via": "api",
      "metadata": {
        "crm_record": "006Qy00000AbCdE"
      },
      "created": 1791576000,
      "sent_at": 1791576300,
      "completed_at": null,
      "expires_at": 1792785900,
      "voided_at": null,
      "void_reason": null,
      "documents": [
        {
          "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
          "object": "document",
          "name": "order-form.pdf",
          "page_count": 3,
          "size": 184320,
          "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
          "signed_sha256": null,
          "converted_from": null,
          "created": 1791576060
        }
      ],
      "recipients": [
        {
          "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
          "object": "recipient",
          "name": "Amara Okafor",
          "email": "amara.okafor@example.com",
          "role": "signer",
          "routing_order": 1,
          "status": "sent",
          "identity_required": false,
          "identity_status": null,
          "sent_at": 1791576300,
          "viewed_at": null,
          "signed_at": null,
          "declined_at": null,
          "decline_reason": null
        },
        {
          "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
          "object": "recipient",
          "name": "Ben Hughes",
          "email": "ben.hughes@example.com",
          "role": "signer",
          "routing_order": 2,
          "status": "created",
          "identity_required": false,
          "identity_status": null,
          "sent_at": null,
          "viewed_at": null,
          "signed_at": null,
          "declined_at": null,
          "decline_reason": null
        }
      ],
      "fields": null
    }
  ]
}

Send an envelope

Sends a draft envelope for signature. Each signer whose turn it is gets an email with their own signing link. Under sequential routing, the next people are emailed as each routing order finishes.

An envelope can be sent when it has at least one document, at least one signer, and at least one field for every signer.

POST/v1/envelopes/:id/send

Parameters

  • expires_in_daysintegeroptional

    How long the signing links work: 7, 14, 30, 60 or 90 days. Defaults to 30. Links never last forever, because a link is all a signer needs to sign.

Returns

Returns the envelope object with status set to sent. Past the envelope allowance on Business it still sends, and is billed. Returns 400 if the envelope is not ready to send, 402 if a plan limit stops it, such as the free plan's five a month or the identity check allowance, and 429 if the account has used its hour's signing emails.

POST/v1/envelopes/:id/send
curl https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b/send \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "expires_in_days": 14
  }'
Response
{
  "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
  "object": "envelope",
  "status": "sent",
  "subject": "Order form, Northwind Traders",
  "message": "Please sign by Friday.",
  "routing_mode": "sequential",
  "sender_email": "sales@yourcompany.com",
  "created_via": "api",
  "metadata": {
    "crm_record": "006Qy00000AbCdE"
  },
  "created": 1791576000,
  "sent_at": 1791576300,
  "completed_at": null,
  "expires_at": 1792785900,
  "voided_at": null,
  "void_reason": null,
  "documents": [
    {
      "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "object": "document",
      "name": "order-form.pdf",
      "page_count": 3,
      "size": 184320,
      "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
      "signed_sha256": null,
      "converted_from": null,
      "created": 1791576060
    }
  ],
  "recipients": [
    {
      "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "object": "recipient",
      "name": "Amara Okafor",
      "email": "amara.okafor@example.com",
      "role": "signer",
      "routing_order": 1,
      "status": "sent",
      "identity_required": false,
      "identity_status": null,
      "sent_at": 1791576300,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    },
    {
      "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "object": "recipient",
      "name": "Ben Hughes",
      "email": "ben.hughes@example.com",
      "role": "signer",
      "routing_order": 2,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    }
  ],
  "fields": [
    {
      "id": "fld_5a1c3e7b9d2f4a6c8e0b1d",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.78,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_9e3b5d7f1a2c4e6b8d0f3a",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "date",
      "page_index": 2,
      "x": 0.5,
      "y": 0.79,
      "width": 0.2,
      "height": 0.04,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_0c4e6a8b2d1f3b5c7e9a4f",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.88,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    }
  ]
}

Remind recipients

Emails a reminder to every signer whose turn it is and who has not signed yet. Each reminder carries a fresh link with the envelope's existing expiry, so a reminder never extends how long a link lives.

SignSecure also reminds people on its own: three days after a link is sent, and up to three times. You only need this endpoint to chase sooner.

POST/v1/envelopes/:id/remind

Parameters

No parameters.

Returns

Returns the envelope object. Returns 409 if the envelope is not out for signature, and 429 if it was reminded in the last hour.

POST/v1/envelopes/:id/remind
curl -X POST https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b/remind
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"
Response
{
  "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
  "object": "envelope",
  "status": "sent",
  "subject": "Order form, Northwind Traders",
  "message": "Please sign by Friday.",
  "routing_mode": "sequential",
  "sender_email": "sales@yourcompany.com",
  "created_via": "api",
  "metadata": {
    "crm_record": "006Qy00000AbCdE"
  },
  "created": 1791576000,
  "sent_at": 1791576300,
  "completed_at": null,
  "expires_at": 1792785900,
  "voided_at": null,
  "void_reason": null,
  "documents": [
    {
      "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "object": "document",
      "name": "order-form.pdf",
      "page_count": 3,
      "size": 184320,
      "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
      "signed_sha256": null,
      "converted_from": null,
      "created": 1791576060
    }
  ],
  "recipients": [
    {
      "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "object": "recipient",
      "name": "Amara Okafor",
      "email": "amara.okafor@example.com",
      "role": "signer",
      "routing_order": 1,
      "status": "sent",
      "identity_required": false,
      "identity_status": null,
      "sent_at": 1791576300,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    },
    {
      "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "object": "recipient",
      "name": "Ben Hughes",
      "email": "ben.hughes@example.com",
      "role": "signer",
      "routing_order": 2,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    }
  ],
  "fields": [
    {
      "id": "fld_5a1c3e7b9d2f4a6c8e0b1d",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.78,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_9e3b5d7f1a2c4e6b8d0f3a",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "date",
      "page_index": 2,
      "x": 0.5,
      "y": 0.79,
      "width": 0.2,
      "height": 0.04,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_0c4e6a8b2d1f3b5c7e9a4f",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.88,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    }
  ]
}

Void an envelope

Stops an envelope that is out for signature. Every outstanding link stops working at once, and the people who had not signed are emailed to say it was withdrawn.

Voiding is not deleting. The envelope, its audit trail and any signatures already collected stay as they are.

POST/v1/envelopes/:id/void

Parameters

  • reasonstringoptional

    Why, up to 500 characters. Included in the email to recipients.

Returns

Returns the envelope object with status set to voided. Returns 409 for a draft, which has nothing to withdraw, and for a completed envelope.

POST/v1/envelopes/:id/void
curl https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b/void \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Pricing changed; a new version is coming."
  }'
Response
{
  "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
  "object": "envelope",
  "status": "voided",
  "subject": "Order form, Northwind Traders",
  "message": "Please sign by Friday.",
  "routing_mode": "sequential",
  "sender_email": "sales@yourcompany.com",
  "created_via": "api",
  "metadata": {
    "crm_record": "006Qy00000AbCdE"
  },
  "created": 1791576000,
  "sent_at": 1791576300,
  "completed_at": null,
  "expires_at": 1792785900,
  "voided_at": 1791579600,
  "void_reason": "Pricing changed; a new version is coming.",
  "documents": [
    {
      "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "object": "document",
      "name": "order-form.pdf",
      "page_count": 3,
      "size": 184320,
      "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
      "signed_sha256": null,
      "converted_from": null,
      "created": 1791576060
    }
  ],
  "recipients": [
    {
      "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "object": "recipient",
      "name": "Amara Okafor",
      "email": "amara.okafor@example.com",
      "role": "signer",
      "routing_order": 1,
      "status": "sent",
      "identity_required": false,
      "identity_status": null,
      "sent_at": 1791576300,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    },
    {
      "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "object": "recipient",
      "name": "Ben Hughes",
      "email": "ben.hughes@example.com",
      "role": "signer",
      "routing_order": 2,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    }
  ],
  "fields": [
    {
      "id": "fld_5a1c3e7b9d2f4a6c8e0b1d",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.78,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_9e3b5d7f1a2c4e6b8d0f3a",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "date",
      "page_index": 2,
      "x": 0.5,
      "y": 0.79,
      "width": 0.2,
      "height": 0.04,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_0c4e6a8b2d1f3b5c7e9a4f",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.88,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    }
  ]
}

Retrieve the audit trail

Returns everything that has happened to an envelope, in order: who created and sent it, who opened it and from where, who signed, and what was produced.

Each entry carries the hash of the one before it, so the trail is a chain. intact is true when every link checks out and nothing has been removed from the end. The data on each entry depends on its type.

GET/v1/envelopes/:id/audit_trail

Parameters

No parameters.

Returns

Returns an audit trail object.

GET/v1/envelopes/:id/audit_trail
curl https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b/audit_trail
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"
Response
{
  "object": "audit_trail",
  "envelope": "env_3f9a1c7e2b8d4a6f9c0e1b",
  "intact": true,
  "entries": [
    {
      "sequence": 1,
      "type": "envelope.created",
      "actor_email": "sales@yourcompany.com",
      "ip": "203.0.113.24",
      "user_agent": "node",
      "data": {
        "via": "api",
        "apiKey": "ss_live_Ab3x"
      },
      "created": 1791576000,
      "hash": "c1d9…",
      "previous_hash": "genesis"
    },
    {
      "sequence": 9,
      "type": "recipient.signed",
      "actor_email": "amara.okafor@example.com",
      "ip": "198.51.100.7",
      "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X)",
      "data": {
        "recipient": "Amara Okafor",
        "stateDigest": "7e0a…",
        "fields": 2
      },
      "created": 1791577620,
      "hash": "5f2b…",
      "previous_hash": "0a7e…"
    }
  ]
}

Documents

A document is a file on an envelope: the thing people sign. Upload a PDF, a Word .docx, or a PNG or JPEG. Word documents and images are converted to PDF when they are uploaded, and the original is kept.

When the last signer finishes, SignSecure writes every value into the PDF and produces the signed version, with its SHA-256 recorded so anyone can check later that it has not changed.

The document object

Attributes

  • idstring

    Unique identifier for the document.

  • objectstring

    Always document.

  • namestring

    The file name. A converted file is named with .pdf.

  • page_countinteger

    How many pages it has.

  • sizeinteger

    Size of the PDF in bytes.

  • sha256string

    SHA-256 of the PDF as uploaded or converted.

  • signed_sha256nullable string

    SHA-256 of the signed PDF, once there is one.

  • converted_fromnullable string

    The original file name, if it was converted from Word or an image.

  • createdtimestamp

    When it was uploaded.

The document object
{
  "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
  "object": "document",
  "name": "order-form.pdf",
  "page_count": 3,
  "size": 184320,
  "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
  "signed_sha256": "4b8e2f6a0d3c7b1e5f9a2d6c0b4e8f3a7d1c5b9e2f6a0c4d8b3e7f1a5c9d2b6e",
  "converted_from": null,
  "created": 1791576060
}

Upload a document

Adds a document to a draft envelope. Send it as multipart/form-data with the file in a part called file.

If building a multipart body is awkward on your platform, send JSON instead, with the file base64-encoded in content. Salesforce Apex is the usual reason.

POST/v1/envelopes/:id/documents

Parameters

  • filefilerequired for multipart

    The file, up to 8 MB: a PDF, a Word .docx, or a PNG or JPEG.

  • namestringrequired for JSON

    The file name, including its extension, which decides how it is read.

  • contentstringrequired for JSON

    The file, base64-encoded.

Returns

Returns the document object. Returns 413 if the file is too large, 415 if it is not a type SignSecure can read, and 409 if the envelope has been sent.

POST/v1/envelopes/:id/documents
curl https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b/documents \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -F file=@order-form.pdf
Response
{
  "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
  "object": "document",
  "name": "order-form.pdf",
  "page_count": 3,
  "size": 184320,
  "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
  "signed_sha256": null,
  "converted_from": null,
  "created": 1791576060
}

Download a document

Downloads a document's file. By default you get the signed PDF, which exists once everyone has signed.

GET/v1/envelopes/:id/documents/:document_id/content

Parameters

  • versionenumoptional

    Which file. Defaults to signed.

    signed The completed PDF, with every value written in.
    original The PDF as it was uploaded or converted, before anyone signed.
    source The original Word file or image, for a document that was converted.

Returns

Returns the file itself, not JSON. Returns 409 with the code invalid_state if you ask for signed before the envelope is completed.

GET/v1/envelopes/:id/documents/:document_id/content
curl https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b/documents/doc_1b4d7f0a3c6e9b2d5f8a1c/content \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -o order-form-signed.pdf
Response
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="order-form.pdf"

%PDF-1.7 …

Delete a document

Removes a document from a draft envelope, along with any fields placed on it.

DELETE/v1/envelopes/:id/documents/:document_id

Parameters

No parameters.

Returns

Returns an object with deleted set to true. Returns 409 if the envelope has been sent.

DELETE/v1/envelopes/:id/documents/:document_id
curl -X DELETE https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b/documents/doc_1b4d7f0a3c6e9b2d5f8a1c
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"
Response
{
  "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
  "object": "document",
  "deleted": true
}

Recipients

A recipient is a person on an envelope. A signer signs; a copy recipient signs nothing and gets the finished document.

The recipient object

Attributes

  • idstring

    Unique identifier for the recipient.

  • objectstring

    Always recipient.

  • namestring

    Their full name.

  • emailstring

    Their email address, in lower case.

  • roleenum

    signer or copy.

  • routing_orderinteger

    When they sign under sequential routing.

  • statusenum

    Where this person is.

    created Not contacted yet.
    sent Emailed a signing link.
    viewed Opened the document.
    signed Finished signing.
    declined Declined to sign.
  • identity_requiredboolean

    Whether they must prove who they are before signing.

  • identity_statusnullable enum

    The identity check, if one was asked for: requires_input, processing, verified or canceled.

  • sent_atnullable timestamp

    When they were last emailed a link.

  • viewed_atnullable timestamp

    When they first opened it.

  • signed_atnullable timestamp

    When they signed.

  • declined_atnullable timestamp

    When they declined.

  • decline_reasonnullable string

    What they said when they declined, if anything.

The recipient object
{
  "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
  "object": "recipient",
  "name": "Amara Okafor",
  "email": "amara.okafor@example.com",
  "role": "signer",
  "routing_order": 1,
  "status": "signed",
  "identity_required": false,
  "identity_status": null,
  "sent_at": 1791576300,
  "viewed_at": 1791577500,
  "signed_at": 1791577620,
  "declined_at": null,
  "decline_reason": null
}

Set the recipients

Replaces the recipients on a draft envelope with the list you send. Anyone not in the list is removed.

Setting the recipients removes every field already placed, because each field belongs to a person and the people have changed. Set recipients first, then fields.

PUT/v1/envelopes/:id/recipients

Parameters

  • recipientsarrayRequired

    The people on the envelope, at least one of them a signer, at most 50.

    Child parameters
    • namestringRequired

      Their full name.

    • emailstringRequired

      Their email address.

    • roleenumoptional

      signer or copy. Defaults to signer.

    • routing_orderintegeroptional

      From 1 to 999. Defaults to their position in the list.

    • identity_requiredbooleanoptional

      Ask this signer for photo ID before signing.

  • routing_modeenumoptional

    sequential or parallel. Leave it out to keep the current one.

Returns

Returns the envelope object. Returns 409 if the envelope has been sent.

PUT/v1/envelopes/:id/recipients
curl -X PUT https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b/recipients \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipients": [
      {
        "name": "Amara Okafor",
        "email": "amara.okafor@example.com"
      },
      {
        "name": "Ben Hughes",
        "email": "ben.hughes@example.com",
        "routing_order": 2
      },
      {
        "name": "Finance team",
        "email": "finance@yourcompany.com",
        "role": "copy"
      }
    ]
  }'
Response
{
  "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
  "object": "envelope",
  "status": "draft",
  "subject": "Order form, Northwind Traders",
  "message": "Please sign by Friday.",
  "routing_mode": "sequential",
  "sender_email": "sales@yourcompany.com",
  "created_via": "api",
  "metadata": {
    "crm_record": "006Qy00000AbCdE"
  },
  "created": 1791576000,
  "sent_at": null,
  "completed_at": null,
  "expires_at": null,
  "voided_at": null,
  "void_reason": null,
  "documents": [],
  "recipients": [
    {
      "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "object": "recipient",
      "name": "Amara Okafor",
      "email": "amara.okafor@example.com",
      "role": "signer",
      "routing_order": 1,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    },
    {
      "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "object": "recipient",
      "name": "Ben Hughes",
      "email": "ben.hughes@example.com",
      "role": "signer",
      "routing_order": 2,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    }
  ],
  "fields": []
}

Correct a recipient

Fixes the name or email of someone on an envelope that is already out for signature, and sends them a new link. The old link stops working first, so a link that went to a mistyped address cannot be used.

You cannot correct someone who has already signed or declined, and each person can be corrected three times a day. Correcting someone's email address means they verify their identity again, if the envelope asks for it.

POST/v1/envelopes/:id/recipients/:recipient_id

Parameters

  • namestringoptional

    Their corrected name.

  • emailstringoptional

    Their corrected email address.

Returns

Returns the envelope object. Returns 409 if the envelope is not out for signature or the person has signed or declined, and 429 once they have been corrected three times today.

POST/v1/envelopes/:id/recipients/:recipient_id
curl https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b/recipients/rcp_7c2e9b1a4f6d8e0c3b5a7d \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "amara@example.com"
  }'

Fields

A field is a place on a document where one signer does something: signs, initials, ticks a box, or types a value. Every signer needs at least one field before an envelope can be sent.

Coordinates. A field's position is given as fractions of the page, from 0 to 1, measured from the top-left corner. x: 0.5, y: 0.25 is halfway across and a quarter of the way down, whatever the page size. To convert from PDF points, divide by the page width or height; remember PDF points are usually measured from the bottom, so y = 1 - (points_from_bottom + height_in_points) / page_height.

page_index counts from 0 within the document.

The field object

Attributes

  • idstring

    Unique identifier for the field.

  • objectstring

    Always field.

  • documentstring

    The id of the document it is on.

  • recipientstring

    The id of the signer who fills it in.

  • typeenum

    What kind of field.

    signature A drawn or typed signature.
    initials Drawn or typed initials.
    date The date they sign, filled in for them.
    name Their name, filled in for them and editable.
    email Their email address, filled in for them and editable.
    text Anything they type, up to 500 characters.
    checkbox A box they tick. The value is X when ticked.
  • page_indexinteger

    The page, counting from 0.

  • xnumber

    Distance from the left edge, as a fraction of the page width.

  • ynumber

    Distance from the top edge, as a fraction of the page height.

  • widthnumber

    As a fraction of the page width.

  • heightnumber

    As a fraction of the page height.

  • requiredboolean

    Whether the signer must fill it in to finish.

  • labelnullable string

    A hint shown to the signer.

  • valuenullable string

    What was entered. Always null for signature and initials, whose value is an image: download the signed PDF to see it.

  • filledboolean

    Whether it has been filled in.

  • filled_atnullable timestamp

    When it was filled in.

The field object
{
  "id": "fld_9e3b5d7f1a2c4e6b8d0f3a",
  "object": "field",
  "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
  "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
  "type": "date",
  "page_index": 2,
  "x": 0.5,
  "y": 0.79,
  "width": 0.2,
  "height": 0.04,
  "required": true,
  "label": null,
  "value": "8 October 2026",
  "filled": true,
  "filled_at": 1791577620
}

Set the fields

Replaces every field on a draft envelope with the list you send. Upload the documents and set the recipients first: each field names one of each.

PUT/v1/envelopes/:id/fields

Parameters

  • fieldsarrayRequired

    Up to 500 fields.

    Child parameters
    • documentstringRequired

      The id of a document on this envelope.

    • recipientstringRequired

      The id of a signer on this envelope. copy recipients cannot have fields.

    • typeenumRequired

      signature, initials, date, name, email, text or checkbox.

    • page_indexintegerRequired

      The page, counting from 0.

    • xnumberRequired

      From the left edge, 0 to 1.

    • ynumberRequired

      From the top edge, 0 to 1.

    • widthnumberRequired

      Greater than 0. x + width cannot pass 1.

    • heightnumberRequired

      Greater than 0. y + height cannot pass 1.

    • requiredbooleanoptional

      Defaults to true.

    • labelstringoptional

      A hint for the signer, up to 120 characters.

Returns

Returns the envelope object, with its fields. Returns 400 if a field is off the page or names a document or signer not on the envelope.

PUT/v1/envelopes/:id/fields
curl -X PUT https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b/fields \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": [
      {
        "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
        "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
        "type": "signature",
        "page_index": 2,
        "x": 0.12,
        "y": 0.78,
        "width": 0.3,
        "height": 0.06
      },
      {
        "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
        "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
        "type": "date",
        "page_index": 2,
        "x": 0.5,
        "y": 0.79,
        "width": 0.2,
        "height": 0.04
      },
      {
        "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
        "recipient": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
        "type": "signature",
        "page_index": 2,
        "x": 0.12,
        "y": 0.88,
        "width": 0.3,
        "height": 0.06
      }
    ]
  }'
Response
{
  "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
  "object": "envelope",
  "status": "draft",
  "subject": "Order form, Northwind Traders",
  "message": "Please sign by Friday.",
  "routing_mode": "sequential",
  "sender_email": "sales@yourcompany.com",
  "created_via": "api",
  "metadata": {
    "crm_record": "006Qy00000AbCdE"
  },
  "created": 1791576000,
  "sent_at": null,
  "completed_at": null,
  "expires_at": null,
  "voided_at": null,
  "void_reason": null,
  "documents": [
    {
      "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "object": "document",
      "name": "order-form.pdf",
      "page_count": 3,
      "size": 184320,
      "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
      "signed_sha256": null,
      "converted_from": null,
      "created": 1791576060
    }
  ],
  "recipients": [
    {
      "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "object": "recipient",
      "name": "Amara Okafor",
      "email": "amara.okafor@example.com",
      "role": "signer",
      "routing_order": 1,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    },
    {
      "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "object": "recipient",
      "name": "Ben Hughes",
      "email": "ben.hughes@example.com",
      "role": "signer",
      "routing_order": 2,
      "status": "created",
      "identity_required": false,
      "identity_status": null,
      "sent_at": null,
      "viewed_at": null,
      "signed_at": null,
      "declined_at": null,
      "decline_reason": null
    }
  ],
  "fields": [
    {
      "id": "fld_5a1c3e7b9d2f4a6c8e0b1d",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.78,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_9e3b5d7f1a2c4e6b8d0f3a",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "type": "date",
      "page_index": 2,
      "x": 0.5,
      "y": 0.79,
      "width": 0.2,
      "height": 0.04,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    },
    {
      "id": "fld_0c4e6a8b2d1f3b5c7e9a4f",
      "object": "field",
      "document": "doc_1b4d7f0a3c6e9b2d5f8a1c",
      "recipient": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
      "type": "signature",
      "page_index": 2,
      "x": 0.12,
      "y": 0.88,
      "width": 0.3,
      "height": 0.06,
      "required": true,
      "label": null,
      "value": null,
      "filled": false,
      "filled_at": null
    }
  ]
}

Apply a template

Lays a saved template's fields onto a draft envelope for one signer. That signer's existing fields are replaced; everyone else's are kept, so you can apply the same template once per signer.

Template pages are counted across all the envelope's documents in order, the way the app shows them. Fields for pages the envelope does not have are skipped.

POST/v1/envelopes/:id/apply_template

Parameters

  • templatestringRequired

    The id of a template.

  • recipientstringoptional

    The id of the signer the fields are for. Defaults to the first signer.

Returns

Returns the envelope object. Returns 409 if none of the template's fields fit the envelope's pages.

POST/v1/envelopes/:id/apply_template
curl https://www.signsecure.org/v1/v1/envelopes/env_3f9a1c7e2b8d4a6f9c0e1b/apply_template \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "tpl_6b8d0f2a4c1e3a5b7d9f0c",
    "recipient": "rcp_7c2e9b1a4f6d8e0c3b5a7d"
  }'

Templates

A template is a saved layout of fields, with no document and no people in it, so the same layout can be laid onto next week's copy of the same form. Templates are saved in the app, from any envelope you have placed fields on.

The template object

Attributes

  • idstring

    Unique identifier for the template.

  • objectstring

    Always template.

  • namestring

    The name it was saved under.

  • field_countinteger

    How many fields it places.

  • page_countinteger

    How many pages the envelope it was saved from had.

  • updatedtimestamp

    When it was last saved.

The template object
{
  "id": "tpl_6b8d0f2a4c1e3a5b7d9f0c",
  "object": "template",
  "name": "Standard order form",
  "field_count": 4,
  "page_count": 3,
  "updated": 1791489600
}

List all templates

Returns every template in your organisation, most recently saved first.

GET/v1/templates

Parameters

No parameters.

Returns

A list object of templates. has_more is always false.

GET/v1/templates
curl https://www.signsecure.org/v1/v1/templates
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"
Response
{
  "object": "list",
  "url": "/v1/templates",
  "has_more": false,
  "data": [
    {
      "id": "tpl_6b8d0f2a4c1e3a5b7d9f0c",
      "object": "template",
      "name": "Standard order form",
      "field_count": 4,
      "page_count": 3,
      "updated": 1791489600
    }
  ]
}

Account

Your organisation, its plan, its seats, and how much of the envelope allowance it has used. Useful for showing someone which account they have connected, and how close they are to paying for extra envelopes.

The account object

Attributes

  • idstring

    Unique identifier for the organisation.

  • objectstring

    Always account.

  • namestring

    The organisation's name.

  • planenum

    business or free.

  • billing_intervalnullable enum

    year or month on Business, null on the free plan.

  • subscription_statusnullable string

    The subscription's status, such as active or past_due.

  • seatsinteger

    Seats paid for. Every Admin and Creator takes one; Viewers and signers are free. The free plan has one.

  • seats_in_useinteger

    Seats taken, counting invitations still open for a seat.

  • envelopesobject

    The envelope allowance for the current period.

    Child attributes
    • includedinteger

      Envelopes the plan includes this period: 100 per seat a year on yearly billing, 10 per seat a month on monthly, 5 a month on the free plan.

    • usedinteger

      Envelopes sent since period_start.

    • period_starttimestamp

      When the period began: the subscription's period on Business, the calendar month on the free plan.

    • overage_countinteger

      Envelopes sent past the allowance this period.

    • overage_amountinteger

      What those cost, in pence, on the next invoice.

    • overage_unit_amountnullable integer

      The price of each envelope past the allowance, in pence. null on the free plan, which stops at its allowance instead.

    • currencystring

      Always gbp.

  • identity_checksobject

    allowance and used for the identity check add-on this billing period.

  • api_keyobject

    The key making this request: its prefix, who it acts_as, and its role.

The account object
{
  "id": "org_1f3a5c7e9b0d2f4a6c8e1b",
  "object": "account",
  "name": "Your Company Ltd",
  "plan": "business",
  "billing_interval": "year",
  "subscription_status": "active",
  "seats": 5,
  "seats_in_use": 4,
  "envelopes": {
    "included": 500,
    "used": 212,
    "period_start": 1781208000,
    "overage_count": 0,
    "overage_amount": 0,
    "overage_unit_amount": 200,
    "currency": "gbp"
  },
  "identity_checks": {
    "allowance": 10,
    "used": 3
  },
  "api_key": {
    "prefix": "ss_live_Ab3x",
    "acts_as": "sales@yourcompany.com",
    "role": "creator"
  }
}

Retrieve the account

Retrieves the organisation the API key belongs to.

GET/v1/account

Parameters

No parameters.

Returns

Returns the account object.

GET/v1/account
curl https://www.signsecure.org/v1/v1/account
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"
Response
{
  "id": "org_1f3a5c7e9b0d2f4a6c8e1b",
  "object": "account",
  "name": "Your Company Ltd",
  "plan": "business",
  "billing_interval": "year",
  "subscription_status": "active",
  "seats": 5,
  "seats_in_use": 4,
  "envelopes": {
    "included": 500,
    "used": 212,
    "period_start": 1781208000,
    "overage_count": 0,
    "overage_amount": 0,
    "overage_unit_amount": 200,
    "currency": "gbp"
  },
  "identity_checks": {
    "allowance": 10,
    "used": 3
  },
  "api_key": {
    "prefix": "ss_live_Ab3x",
    "acts_as": "sales@yourcompany.com",
    "role": "creator"
  }
}

Events

An event is a record of something that happened to an envelope. Events are what webhooks send, and you can also list them, which is how an integration catches up after missing a delivery.

Events are kept for 30 days. Each one holds the envelope as it was at that moment, in data.object, without its fields, which can run to hundreds; retrieve the envelope if you need them. Events about one person, recipient.viewed and recipient.signed, also carry that person in data.recipient. envelope.declined carries the person who declined.

The event object

Attributes

  • idstring

    Unique identifier for the event. Use it to ignore a delivery you have already handled.

  • objectstring

    Always event.

  • typestring

    What happened. See types of events.

  • createdtimestamp

    When it happened.

  • dataobject

    object is the envelope at that moment. recipient, on recipient events, is the person it was about.

The event object
{
  "id": "evt_4e6a8c0b2d3f5a7c9e1b2d",
  "object": "event",
  "type": "envelope.completed",
  "created": 1791583201,
  "data": {
    "object": {
      "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
      "object": "envelope",
      "status": "completed",
      "subject": "Order form, Northwind Traders",
      "message": "Please sign by Friday.",
      "routing_mode": "sequential",
      "sender_email": "sales@yourcompany.com",
      "created_via": "api",
      "metadata": {
        "crm_record": "006Qy00000AbCdE"
      },
      "created": 1791576000,
      "sent_at": 1791576300,
      "completed_at": 1791583200,
      "expires_at": 1792785900,
      "voided_at": null,
      "void_reason": null,
      "documents": [
        {
          "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
          "object": "document",
          "name": "order-form.pdf",
          "page_count": 3,
          "size": 184320,
          "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
          "signed_sha256": "4b8e2f6a0d3c7b1e5f9a2d6c0b4e8f3a7d1c5b9e2f6a0c4d8b3e7f1a5c9d2b6e",
          "converted_from": null,
          "created": 1791576060
        }
      ],
      "recipients": [
        {
          "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
          "object": "recipient",
          "name": "Amara Okafor",
          "email": "amara.okafor@example.com",
          "role": "signer",
          "routing_order": 1,
          "status": "signed",
          "identity_required": false,
          "identity_status": null,
          "sent_at": 1791576300,
          "viewed_at": 1791577500,
          "signed_at": 1791577620,
          "declined_at": null,
          "decline_reason": null
        },
        {
          "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
          "object": "recipient",
          "name": "Ben Hughes",
          "email": "ben.hughes@example.com",
          "role": "signer",
          "routing_order": 2,
          "status": "signed",
          "identity_required": false,
          "identity_status": null,
          "sent_at": 1791577620,
          "viewed_at": 1791582900,
          "signed_at": 1791583200,
          "declined_at": null,
          "decline_reason": null
        }
      ],
      "fields": null
    }
  }
}

Types of events

This is every event type SignSecure sends. New types may be added; ignore any you do not recognise.

TypeOccurs when
envelope.sentAn envelope was sent for signature.
recipient.viewedA signer opened the document for the first time.
recipient.signedA signer finished signing. Others may still need to.
envelope.completedEveryone has signed. The signed PDF is ready to download.
envelope.declinedA signer declined. Nobody else will be asked to sign.
envelope.voidedThe envelope was voided.
envelope.expiredThe signing links ran out before everyone signed.
A recipient event
{
  "id": "evt_8c0e2a4b6d1f3a5c7e9b0d2f",
  "object": "event",
  "type": "recipient.signed",
  "created": 1791577621,
  "data": {
    "object": "…the envelope…",
    "recipient": {
      "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
      "object": "recipient",
      "name": "Amara Okafor",
      "email": "amara.okafor@example.com",
      "role": "signer",
      "routing_order": 1,
      "status": "signed",
      "identity_required": false,
      "identity_status": null,
      "sent_at": 1791576300,
      "viewed_at": 1791577500,
      "signed_at": 1791577620,
      "declined_at": null,
      "decline_reason": null
    }
  }
}

List all events

Returns events from the last 30 days, newest first.

GET/v1/events

Parameters

  • typestringoptional

    Only events of this type.

  • envelopestringoptional

    Only events about this envelope.

  • limitintegeroptional

    From 1 to 100. Defaults to 10.

  • starting_afterstringoptional

    A cursor for pagination.

Returns

A list object of events.

GET/v1/events
curl https://www.signsecure.org/v1/v1/events?type=envelope.completed&limit=10
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"
Response
{
  "object": "list",
  "url": "/v1/events",
  "has_more": false,
  "data": [
    {
      "id": "evt_4e6a8c0b2d3f5a7c9e1b2d",
      "object": "event",
      "type": "envelope.completed",
      "created": 1791583201,
      "data": {
        "object": {
          "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
          "object": "envelope",
          "status": "completed",
          "subject": "Order form, Northwind Traders",
          "message": "Please sign by Friday.",
          "routing_mode": "sequential",
          "sender_email": "sales@yourcompany.com",
          "created_via": "api",
          "metadata": {
            "crm_record": "006Qy00000AbCdE"
          },
          "created": 1791576000,
          "sent_at": 1791576300,
          "completed_at": 1791583200,
          "expires_at": 1792785900,
          "voided_at": null,
          "void_reason": null,
          "documents": [
            {
              "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
              "object": "document",
              "name": "order-form.pdf",
              "page_count": 3,
              "size": 184320,
              "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
              "signed_sha256": "4b8e2f6a0d3c7b1e5f9a2d6c0b4e8f3a7d1c5b9e2f6a0c4d8b3e7f1a5c9d2b6e",
              "converted_from": null,
              "created": 1791576060
            }
          ],
          "recipients": [
            {
              "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
              "object": "recipient",
              "name": "Amara Okafor",
              "email": "amara.okafor@example.com",
              "role": "signer",
              "routing_order": 1,
              "status": "signed",
              "identity_required": false,
              "identity_status": null,
              "sent_at": 1791576300,
              "viewed_at": 1791577500,
              "signed_at": 1791577620,
              "declined_at": null,
              "decline_reason": null
            },
            {
              "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
              "object": "recipient",
              "name": "Ben Hughes",
              "email": "ben.hughes@example.com",
              "role": "signer",
              "routing_order": 2,
              "status": "signed",
              "identity_required": false,
              "identity_status": null,
              "sent_at": 1791577620,
              "viewed_at": 1791582900,
              "signed_at": 1791583200,
              "declined_at": null,
              "decline_reason": null
            }
          ],
          "fields": null
        }
      }
    }
  ]
}

Retrieve an event

Retrieves an event from the last 30 days.

GET/v1/events/:id

Parameters

No parameters.

Returns

Returns the event object.

GET/v1/events/:id
curl https://www.signsecure.org/v1/v1/events/evt_4e6a8c0b2d3f5a7c9e1b2d
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"
Response
{
  "id": "evt_4e6a8c0b2d3f5a7c9e1b2d",
  "object": "event",
  "type": "envelope.completed",
  "created": 1791583201,
  "data": {
    "object": {
      "id": "env_3f9a1c7e2b8d4a6f9c0e1b",
      "object": "envelope",
      "status": "completed",
      "subject": "Order form, Northwind Traders",
      "message": "Please sign by Friday.",
      "routing_mode": "sequential",
      "sender_email": "sales@yourcompany.com",
      "created_via": "api",
      "metadata": {
        "crm_record": "006Qy00000AbCdE"
      },
      "created": 1791576000,
      "sent_at": 1791576300,
      "completed_at": 1791583200,
      "expires_at": 1792785900,
      "voided_at": null,
      "void_reason": null,
      "documents": [
        {
          "id": "doc_1b4d7f0a3c6e9b2d5f8a1c",
          "object": "document",
          "name": "order-form.pdf",
          "page_count": 3,
          "size": 184320,
          "sha256": "9f2c6e1a7b4d8c3f0e5a9b2d6c1f4e8a3b7d0c5f9e2a6b1d4c8f3e7a0b5d9c2f",
          "signed_sha256": "4b8e2f6a0d3c7b1e5f9a2d6c0b4e8f3a7d1c5b9e2f6a0c4d8b3e7f1a5c9d2b6e",
          "converted_from": null,
          "created": 1791576060
        }
      ],
      "recipients": [
        {
          "id": "rcp_7c2e9b1a4f6d8e0c3b5a7d",
          "object": "recipient",
          "name": "Amara Okafor",
          "email": "amara.okafor@example.com",
          "role": "signer",
          "routing_order": 1,
          "status": "signed",
          "identity_required": false,
          "identity_status": null,
          "sent_at": 1791576300,
          "viewed_at": 1791577500,
          "signed_at": 1791577620,
          "declined_at": null,
          "decline_reason": null
        },
        {
          "id": "rcp_2d8f4b6a0c1e3f5a7b9c2e",
          "object": "recipient",
          "name": "Ben Hughes",
          "email": "ben.hughes@example.com",
          "role": "signer",
          "routing_order": 2,
          "status": "signed",
          "identity_required": false,
          "identity_status": null,
          "sent_at": 1791577620,
          "viewed_at": 1791582900,
          "signed_at": 1791583200,
          "declined_at": null,
          "decline_reason": null
        }
      ],
      "fields": null
    }
  }
}

Webhook endpoints

A webhook endpoint is a URL on your server that SignSecure sends events to as they happen. The webhooks guide covers receiving them and checking their signatures. You can also manage endpoints under Developers in the app.

An endpoint receives every envelope in the organisation, so managing them needs a key created by someone who is an admin now. A key whose creator has since become a Creator or Viewer gets 403.

The webhook endpoint object

Attributes

  • idstring

    Unique identifier for the endpoint.

  • objectstring

    Always webhook_endpoint.

  • urlstring

    Where events are sent.

  • enabled_eventsarray of strings

    The event types sent here, or ["*"] for all of them.

  • descriptionnullable string

    Your note about it.

  • statusenum

    enabled, or disabled if you turned it off or it failed for several days in a row.

  • createdtimestamp

    When it was created.

  • last_attempt_atnullable timestamp

    When a delivery was last attempted.

  • last_statusnullable integer

    The HTTP status your server returned to that attempt, or null if it did not answer.

  • secretstring

    The signing secret. Only returned when the endpoint is created.

The webhook endpoint object
{
  "id": "we_8a0c2e4b6d1f3a5c7e9b0d",
  "object": "webhook_endpoint",
  "url": "https://hooks.yourcompany.com/signsecure",
  "enabled_events": [
    "envelope.completed",
    "envelope.declined"
  ],
  "description": "CRM sync",
  "status": "enabled",
  "created": 1791576000,
  "last_attempt_at": null,
  "last_status": null
}

Create a webhook endpoint

Creates an endpoint. The response includes its signing secret, which is shown this once. Store it with your other secrets: you need it to check that each delivery came from SignSecure.

POST/v1/webhook_endpoints

Parameters

  • urlstringRequired

    An https URL with a public hostname, on port 443 or 8443. IP addresses and private hostnames are refused.

  • enabled_eventsarray of stringsRequired

    The event types to send, or ["*"] for all of them.

  • descriptionstringoptional

    A note for yourself, up to 200 characters.

Returns

Returns the webhook endpoint object, including secret.

POST/v1/webhook_endpoints
curl https://www.signsecure.org/v1/v1/webhook_endpoints \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.yourcompany.com/signsecure",
    "enabled_events": [
      "envelope.completed",
      "envelope.declined"
    ],
    "description": "CRM sync"
  }'
Response
{
  "id": "we_8a0c2e4b6d1f3a5c7e9b0d",
  "object": "webhook_endpoint",
  "url": "https://hooks.yourcompany.com/signsecure",
  "enabled_events": [
    "envelope.completed",
    "envelope.declined"
  ],
  "description": "CRM sync",
  "status": "enabled",
  "created": 1791576000,
  "last_attempt_at": null,
  "last_status": null,
  "secret": "whsec_Xq3vK8mN2pR5tW9yB4cF7hJ0lS6dG1aE3uZ8iO2nV5k"
}

Retrieve a webhook endpoint

Retrieves an endpoint. The secret is not included.

GET/v1/webhook_endpoints/:id

Parameters

No parameters.

Returns

Returns the webhook endpoint object.

GET/v1/webhook_endpoints/:id
curl https://www.signsecure.org/v1/v1/webhook_endpoints/we_8a0c2e4b6d1f3a5c7e9b0d
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"
Response
{
  "id": "we_8a0c2e4b6d1f3a5c7e9b0d",
  "object": "webhook_endpoint",
  "url": "https://hooks.yourcompany.com/signsecure",
  "enabled_events": [
    "envelope.completed",
    "envelope.declined"
  ],
  "description": "CRM sync",
  "status": "enabled",
  "created": 1791576000,
  "last_attempt_at": null,
  "last_status": null
}

Update a webhook endpoint

Updates an endpoint. Parameters you leave out are unchanged.

POST/v1/webhook_endpoints/:id

Parameters

  • urlstringoptional

    A new URL, with the same rules as when creating one.

  • enabled_eventsarray of stringsoptional

    Replaces the list of event types.

  • descriptionstringoptional

    A note for yourself.

  • disabledbooleanoptional

    true stops deliveries. false turns the endpoint back on, including one that was switched off after repeated failures; if it fails ten more times in a row it is switched off again.

Returns

Returns the webhook endpoint object.

POST/v1/webhook_endpoints/:id
curl https://www.signsecure.org/v1/v1/webhook_endpoints/we_8a0c2e4b6d1f3a5c7e9b0d \
  -H "Authorization: Bearer $SIGNSECURE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled_events": [
      "*"
    ]
  }'
Response
{
  "id": "we_8a0c2e4b6d1f3a5c7e9b0d",
  "object": "webhook_endpoint",
  "url": "https://hooks.yourcompany.com/signsecure",
  "enabled_events": [
    "*"
  ],
  "description": "CRM sync",
  "status": "enabled",
  "created": 1791576000,
  "last_attempt_at": null,
  "last_status": null
}

List all webhook endpoints

Returns every endpoint on the account.

GET/v1/webhook_endpoints

Parameters

No parameters.

Returns

A list object of webhook endpoints.

GET/v1/webhook_endpoints
curl https://www.signsecure.org/v1/v1/webhook_endpoints
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"
Response
{
  "object": "list",
  "url": "/v1/webhook_endpoints",
  "has_more": false,
  "data": [
    {
      "id": "we_8a0c2e4b6d1f3a5c7e9b0d",
      "object": "webhook_endpoint",
      "url": "https://hooks.yourcompany.com/signsecure",
      "enabled_events": [
        "envelope.completed",
        "envelope.declined"
      ],
      "description": "CRM sync",
      "status": "enabled",
      "created": 1791576000,
      "last_attempt_at": null,
      "last_status": null
    }
  ]
}

Delete a webhook endpoint

Deletes an endpoint. Deliveries to it stop straight away.

DELETE/v1/webhook_endpoints/:id

Parameters

No parameters.

Returns

Returns an object with deleted set to true.

DELETE/v1/webhook_endpoints/:id
curl -X DELETE https://www.signsecure.org/v1/v1/webhook_endpoints/we_8a0c2e4b6d1f3a5c7e9b0d
  -H "Authorization: Bearer $SIGNSECURE_API_KEY"
Response
{
  "id": "we_8a0c2e4b6d1f3a5c7e9b0d",
  "object": "webhook_endpoint",
  "deleted": true
}