The SignRequest REST API enables you to send out signature requests. Using the API you will always have all the functionality as when using the frontend plus more.

When you're logged in, and you have a Team enabled, you can also use the endpoints in your browser by visiting them.

It is also possible to receive events from SignRequest when, for example, a document has been signed. This way you can keep your application in sync with SignRequest without polling document endpoints. For this a callback url needs to be provided in the team api settings page.

In order to use the API you first need to obtain an API token.

API token

You can create an API token in the team api settings page. It is also possible to get or create a token using the REST api with your login credentials.

cURL example:

curl --user email:password --data 'subdomain=the_subdomain_of_your_team' https://signrequest.com/api/v1/api-tokens/

Example response:

{"token":"login_to_see_your_token_here","created":true}

The token, prepended with Token (note the extra space), should now always be set in the Authorization header when making requests to the SignRequest API.

cURL example:

curl -H 'Authorization: Token login_to_see_your_token_here' -H 'Content-Type:application/json'

Create a Document

In order to send out a SignRequest we first need to create a document. There are a three ways to create a document. One by POSTing a file, two by providing file_from_url in which case SignRequest will download the document from that location and three providing base64 encoded document content in file_from_content together with the filename for this content in file_from_content_name. This can be useful if you have trouble POSTing the file together with other (nested, in the case of the signrequest-quick-create endpoint) configuration data. Please be sure to add the correct extension to the filename (e.g. my_pdf_file.pdf) in order for SignRequest to be able to determine the content type of the content.

Note that when using file_from_url this url needs to be available for SignRequest to download. The download location may also be a Google Drive shareable link for documents (application/vnd.google-apps.document) and files (application/vnd.google-apps.file) uploaded to Google Drive. If the download location returns a content type of text/plain or text/html SignRequest will do its best to make a pdf out of it. This can be used if you want to dynamically create pdf documents from web pages without making a pdf yourself. external_id is optional and can be used in order to have a reference to the document in your systems. The name field is also optional and can be customized, defaults to the filename (including extension).

cURL example using file:

curl -X POST -H 'Authorization: Token login_to_see_your_token_here' -H 'Content-Type: multipart/form-data' -F 'file=@/home/user/path/to/your/document.pdf' -F 'external_id=your_id_of_this_document' https://signrequest.com/api/v1/documents/

cURL example using file_from_url:

curl -X POST -H 'Authorization: Token login_to_see_your_token_here' -H 'Content-Type:application/json' -d '{"file_from_url":"","external_id":"your_id_of_this_document"}' https://signrequest.com/api/v1/documents/

Example response:

{
    "api_used": true, 
    "external_id": "your_id_of_this_document", 
    "file": "signrequest download url of the uploaded file", 
    "file_from_url": "url where signrequest downloaded the document, if this functionality was used", 
    "name": "document.pdf", 
    "pdf": null, 
    "security_hash": null, 
    "signing_log": null, 
    "signrequest": null, 
    "status": "co", 
    "team": {
        "name": "the_name_of_your_team", 
        "subdomain": "the_subdomain_of_your_team"
    }, 
    "template": null, 
    "url": "https://signrequest.com/api/v1/documents/f2bac751-4fa1-43f1-91de-a1b8905c239a/", 
    "user": null, 
    "uuid": "f2bac751-4fa1-43f1-91de-a1b8905c239a"
}

Now that we have succesfully created a document we can now send out the actual SignRequest using the value of url (https://signrequest.com/api/v1/documents/f2bac751-4fa1-43f1-91de-a1b8905c239a/) as a reference to the document we just created.

Sending a SignRequest

The minimal data needed to send out a SignRequest is the following:

{
    "document": "https://signrequest.com/api/v1/documents/f2bac751-4fa1-43f1-91de-a1b8905c239a/", 
    "from_email": "contact@signrequest.com", 
    "message": "Please sign this document.\n\nThanks!", 
    "signers": [
        {
            "email": "api@signrequest.com"
        }
    ]
}

cURL example:

curl -X POST -H 'Authorization: Token login_to_see_your_token_here' -H 'Content-Type:application/json' -d '{"document": "https://signrequest.com/api/v1/documents/f2bac751-4fa1-43f1-91de-a1b8905c239a/", "from_email": "contact@signrequest.com", "message": "Please sign this document.\n\nThanks!", "signers": [{"email": "api@signrequest.com"}]}' https://signrequest.com/api/v1/signrequests/

Example response:

{
    "disable_attachments": false, 
    "disable_date": false, 
    "disable_text": false, 
    "disable_text_signatures": false, 
    "disable_upload_signatures": false, 
    "document": "https://signrequest.com/api/v1/documents/f2bac751-4fa1-43f1-91de-a1b8905c239a/", 
    "from_email": "contact@signrequest.com", 
    "from_email_name": null, 
    "integrations": [], 
    "message": "Please sign this document.\n\nThanks!", 
    "rend_reminders": false, 
    "required_attachments": [], 
    "signers": [
        {
            "after_document": null, 
            "approve_only": false, 
            "attachments": [], 
            "declined": false, 
            "declined_on": null, 
            "display_name": "api@signrequest.com", 
            "downloaded": false, 
            "email": "api@signrequest.com", 
            "email_viewed": false, 
            "emailed": false, 
            "embed_url": null, 
            "embed_url_user_id": null, 
            "first_name": null, 
            "force_language": false, 
            "in_person": false, 
            "language": "en", 
            "last_name": null, 
            "message": null, 
            "needs_to_sign": true, 
            "order": 0, 
            "redirect_url": null, 
            "signed": false, 
            "signed_on": null, 
            "verify_bank_account": null, 
            "verify_phone_number": null, 
            "viewed": false
        }, 
        {
            "after_document": null, 
            "approve_only": false, 
            "attachments": [], 
            "declined": false, 
            "declined_on": null, 
            "display_name": "contact@signrequest.com", 
            "downloaded": false, 
            "email": "contact@signrequest.com", 
            "email_viewed": false, 
            "emailed": false, 
            "embed_url": null, 
            "embed_url_user_id": null, 
            "first_name": "", 
            "force_language": false, 
            "in_person": false, 
            "language": "en", 
            "last_name": "", 
            "message": null, 
            "needs_to_sign": false, 
            "order": 0, 
            "redirect_url": null, 
            "signed": false, 
            "signed_on": null, 
            "verify_bank_account": null, 
            "verify_phone_number": null, 
            "viewed": false
        }
    ], 
    "subject": "You've received a SignRequest from the_name_of_your_team (contact@signrequest.com)", 
    "url": "https://signrequest.com/api/v1/signrequests/a894dcb0-f7c6-4f04-80e3-999a6245c78a/", 
    "uuid": "a894dcb0-f7c6-4f04-80e3-999a6245c78a", 
    "who": "o"
}

The SignRequest has now been initiated. Note here that we always also create a signer for the from_email sending the SignRequest, however for this signer the needs_to_sign flag is set to false meaning that this signer will not get a SignRequest.

Customizing the SignRequest email

If the used Team has a custom color and logo these will be used in the SignRequest email. Also the subject and message fields can be used to customize the email even further. The message may contain the following html tags: 'a', 'abbr', 'acronym', 'b', 'blockquote', 'code', 'em', 'i', 'ul', 'li', 'ol', 'strong'. Be aware that when the text to html ratio it too high the email may end up in spam filters. Custom styles on these tags are not allowed.

When the from_email_name field is provided this name will be used in the `From` email header as such '{from_email_name} <no-reply@signrequest.com>'. By default 'Sender Name (sender@email.com) | SignRequest' is used as the 'from_email_name'. Note that it's currently not possible to change the email address used to send a SignRequest.

Resend the SignRequest email(s)

This endpoint can be used to resend the SignRequest email as a reminder to all signers who didn't sign yet but did receive the email before.

cURL example:

curl -X POST -H 'Authorization: Token login_to_see_your_token_here' -H 'Content-Type:application/json' https://signrequest.com/api/v1/signrequests/a894dcb0-f7c6-4f04-80e3-999a6245c78a/resend_signrequest_email/

Cancel a SignRequest

A SignRequest that has not been fully signed or declined yet can be cancelled. By doing so all signers that have not signed yet will not be able to open and sign the document anymore.

cURL example:

curl -X POST -H 'Authorization: Token login_to_see_your_token_here' -H 'Content-Type:application/json' https://signrequest.com/api/v1/signrequests/a894dcb0-f7c6-4f04-80e3-999a6245c78a/cancel_signrequest/

Chaining multiple documents

When sending a SignRequest it's possible to reference a document in the after_document field on a signer. This should reference a document after which the signer should be redirected to when signing that document. Initially these signers do NOT get a SignRequest email as they will be redirected after signing the other document. Note that resending the SignRequest email will trigger the SignRequest email even though they didn't receive one before.

When after_document references a document where the signer in question already has signed or declined they will still receive a SignRequest email as we cannot redirect them anymore. It's only possible to reference documents that are not fully signed (or declined) yet.

Also a redirect_url field is available on a signer. When specified SignRequest will redirect to this url when a document is signed. Note that this only works when there are no chained documents for this signer anymore.

Chaining also works on the signrequest-quick-create endpoint. When creating a SignRequest on that endpoint you get a reference to the created document in the document field back which can be used in the next call to signrequest-quick-create when creating a chain with after_document.

Signer language

If known the language of the signer can be set in the language field. This will determine the language of the SignRequest email. The SignRequest browser interface language is by default set to the location, browser or user account settings when available.

To force the language of the interface when a signer lands on the signing page the field force_language on the signer can be set to true. Note that if the language of the signer is not known it's best to not force the language.

Available languages:

  • en English
  • en-gb English (GB)
  • nl Dutch
  • fr French
  • de German
  • da Danish
  • fi Finnish
  • hu Hungarian
  • it Italian
  • no Norwegian
  • pl Polish
  • pt Portuguese
  • es Spanish
  • sv Swedish

Text message and Bank account verification

For a higher degree of authentication of your signers it is possible to enable Text message phone number verification and Bank account verification. These verifications can be enabled by providing the phone number to verify_phone_number (international format including the plus-sign) and/or the bank account to verify_bank_account on a signer. Currently it is only possible to verify bank accounts using iDEAL.

When enabled, signers can only sign (finalize) a document when they have verified their phone number by a code supplied to them by a text message and/or make a payment of 1 cent. The verifications are logged and visible in the SignRequest signing log after completion.

Please note that we cannot force signers to make a payment using a specific bank account. Therefore the content of the field may also specify what type of account to use instead of a specific bank account number, e.g.: 'the bank account you want to use for paying the rent'.

For this service additional fees apply. Please contact us for a quote.

Disable signing tools/features

It is possible to disable certain tools/features signers have when signing a document. The following flags can be set to true on the signrequest model to disable these features.

  • disable_text disable adding of text.
  • disable_date disable adding of dates.
  • disable_attachments disable uploading/adding of attachments.
  • disable_text_signatures disable usage of signatures generated by typing (text).
  • disable_upload_signatures disable usage of uploaded signatures (images).

Please note that we strongly discourage you to disable features as these are carefully chosen for optimal usability of the SignRequest product.

SignRequest Quick Create

In some cases it might be needed to create a document and send the SignRequest in one api call. This can be done using the signrequest-quick-create endpoint. This endpoint takes all the fields of the documents and signrequests endpoints together, creates the document and sends the SignRequest.

Optionally this endpoint also accepts the multipart/form-data content type if the file is POSTed directly. In order to deal with the nested signers data the fields can be referenced by including the index of the signer, e.g. signer[0]email=some@email.com. If convenient it is also possible to provide the configuration data as json in a field which needs to be called data.

Templates

In the frontend application it is possible to create templates. These templates, for Teams and Personal accounts, can be found in the the templates resource. In order to send a SignRequest using a template, reference the resource url of the template in the template field. This works in both the documents and the signrequest-quick-create resources.

Automatic reminders

To enable automatic reminders set the send_reminders boolean to true on the SignRequest resource. When enabled SignRequest will automatically remind signers to sign a document.

Events callback

In order to receive the events as a callback to your application a callback url needs to be set in the team api settings page. When set, SignRequest will POST events as application/json to this endpoint. Your endpoint should return a 200 OK response. SignRequest will retry to deliver events (max 10 times) in case of a timeout or a 500 response from your server.

It is also possible to change the callback url on a per document basis. To use this functionality you can set the callback url using the events_callback_url field when creating a document or when using the signrequest-quick-create endpoint.

Please be aware that we might add more event types in the future so code defensively for that.

For an example of how an event receiver can we written checkout this repository.

The following events types are available:

  • convert_error: Document convert error
  • converted: Document converted
  • sending_error: Document sending error
  • sent: Document sent
  • declined: Document declined
  • signed: Document signed
  • signer_signed: Signer signed
  • signer_email_bounced: Signer email bounced
  • signer_viewed_email: Signer viewed email
  • signer_viewed: Signer viewed document
  • signer_downloaded: Signer downloaded
  • signrequest_received: SignRequest received

Status codes:

  • ok: ok
  • error: error

The event status will be error for the following events: convert_error , sending_error and signer_email_bounced.

Example callback request:

{
    "document": {
        "api_used": true, 
        "external_id": "your_id_of_this_document", 
        "file": "signrequest download url of the uploaded file", 
        "file_from_url": "url where signrequest downloaded the document, if this functionality was used", 
        "name": "document.pdf", 
        "pdf": null, 
        "security_hash": null, 
        "signing_log": null, 
        "signrequest": null, 
        "status": "co", 
        "team": {
            "name": "the_name_of_your_team", 
            "subdomain": "the_subdomain_of_your_team"
        }, 
        "template": null, 
        "url": "https://signrequest.com/api/v1/documents/f2bac751-4fa1-43f1-91de-a1b8905c239a/", 
        "user": null, 
        "uuid": "f2bac751-4fa1-43f1-91de-a1b8905c239a"
    }, 
    "event_hash": "344634c4017a07f15b525e082f92c9839115fbec2d4a0511517fa8a32ca241b5", 
    "event_time": "1485211987", 
    "event_type": "converted", 
    "signer": null, 
    "status": "ok", 
    "team": {
        "name": "the_name_of_your_team", 
        "subdomain": "the_subdomain_of_your_team"
    }, 
    "timestamp": "2017-01-23T22:53:07.514707Z", 
    "token_name": "Token", 
    "uuid": "e1475fec-d181-4c47-8c24-f4abe923ed6d"
}

If the event is signer related the signer field will contain all the signer data.

You can check the authenticity (that the event really came from SignRequest) by generating and comparing the event_hash that comes with the event. The event_hash is generated with the HMAC algorithm using your API Token as a key in SHA256 digest mode.

OpenSSL shell example:

echo -n "${event_time}${event_type}" | openssl dgst -sha256 -hmac "${token}"

which expands to:

echo -n "1485211987converted" | openssl dgst -sha256 -hmac "login_to_see_your_token_here"
344634c4017a07f15b525e082f92c9839115fbec2d4a0511517fa8a32ca241b5

If you have multiple API tokens created you can identify the used token by the token_name (if you provided one).

Always use SSL enabled endpoints!

Event webhooks

To receive only specific event callbacks, webhook subscriptions can be created for Teams and for Personal accounts. The resource takes a event_type, callback_url and optionally a name to easily identify what webhook is used for. The integration field can also be set when this hook is specific to one of the SignRequest supported integrations. Checkout the webhooks resource for all possible event types to subscribe to. When the webhooks are used on personal accounts these webhooks also receive the signrequest_received event which can be used to notify users that they have received a new SignRequest. However, creating webhook subscriptions for personal accounts requires a SignRequest session (logged in user) or Basic auth using a username and password.

Frontend API

Another option to help your users sending SignRequests is using the 'frontend' api. This involves no token and is merely used to 'prefill' the SignRequest box found at the homepage for your users. The only requirement is that the document to send out is publicly available in order for SignRequest to download the file. Shareable links of Google Drive documents are also supported here.

GET params for prefilling the box:

api=v1  # the version of the api to use
who=mo  # mo='me & others', m='only me', o='only others'
signers=first_email@example.com,second_email@example.com  # emails of 'signers' comma separated
from_email=contact@signrequest.com  # email of the person sending the SignRequest
doc_url=https%3A%2F%2Fsignrequest.com%2Fstatic%2Fdemo%2FSignRequestDemoDocument.pdf  # the url where SignRequest can download the document (quoted)

Example resulting url:

https://signrequest.com/#/?api=v1&who=mo&signers=api@signrequest.com&from_email=contact@signrequest.com&doc_url=https%3A%2F%2Fsignrequest.com%2Fstatic%2Fdemo%2FSignRequestDemoDocument.pdf

SignRequest-js client (beta)

Although we consider the library 'beta' you can count on a stable api (semver). However, if you plan to use this please contact us so we know your usecase and can help you out where needed. We will open up the repository to the public when out of beta.

To use the SignRequest javascript library include the following in your page (npm and bower are coming when out of beta):

<script src="https://cdn.signrequest.com/signrequest-js/v1/signrequest-js.min.js"></script>

Or for async loading use:

<script>
!function(t,e,n,i){var s=function(e,n){t.SignRequest&&t.SignRequest.loaded||setTimeout(function(){t.SignRequest.init(e,n)},50)};t.SignRequest=t.SignRequest||{loaded:0,init:s};var o="https:"==e.location.protocol?"https://":"http://",u=e.createElement("script");u.async=!0;var c=e.scripts[0];u.src=o+"cdn.signrequest.com/signrequest-js/v1/signrequest-js.min.js",c.parentNode.insertBefore(u,c),t.SignRequest.init(n,i)}(window,document,{
  // this initial configuration is optional, may also be undefined
  subdomain: ''  // you could for example initialize the library to use a specific team subdomain here
}, function (SignRequest) {
  // this callback is optional, may also be undefined
  // SignRequest library is loaded and also passed as first argument
  // execute your code...
});
</script>

The library uses UMD (Universal Module Definition).

To use a specific version (current is 1.0.1) use for example: cdn.signrequest.com/signrequest-js/v1/{{ signrequest_js_version }}/signrequest-js.min.js.

Usage

// same as the frontend api GET parameters, these are all optional
var conf = {
    subdomain: '' // if you are using this for a specific team set the subdomain here
    api: 'v1',
    who: 'mo',
    signers: 'first_email@example.com,second_email@example.com',
    from_email: 'contact@signrequest.com',
    close: true,  // close the popup when done? default: true
    // or use next:
    next: '',  // redirect to this url when done signing themselves
}
// these are also optional, the popup will be centered in the window opening the popup
var popup_conf = {
    width: 460,  // width of the popup in pixels, default 460
    height: 600, // height of the popup in pixels, default the height of the window opening the popup
}

// to open a specific document first create a document using the REST api with your backend
// be sure to also set the correct 'subdomain' in the configuration when you create a document for a specific team
var doc_uuid = 'the-uuid-of-the-document';
SignRequest.browser.openPopupForDocUuid(doc_uuid, conf, popup_conf);

// to create a document from a url
var doc_url = 'https://signrequest.com/static/demo/SignRequestDemoDocument.pdf'
SignRequest.browser.openPopupForDocUrl(doc_url, conf, popup_conf);

// to open a popup using custom params
var popup = SignRequest.browser.openPopup(conf, popup_conf);

// all popup openers return an instance of the popup to which event callbacks can be registered (they can be chained)
// the possible events are: 'opened', 'sent', 'signed', 'declined', 'finished', 'closed', 'any'
// note that 'sent', 'finished' and 'closed' can be called fast after each other when the popup autocloses (close: true)
// also when sending a SignRequest and the sender also need to sign you can receive the 'signed' or 'declined' event
// after the 'sent' event (SignRequest created).
// When the sender is done (sending and possibly siging) the 'finished' event is fired.
popup = popup.on('closed', function (event_type, payload, event) {
    // this would fire when the popup closes, you might want to update your page based on events like this
    console.log(event_type, payload, event);
})

// shortcut to fire on all events ('any')
popup.onAny(function (event_type, payload, event) {
    // this would fire on all events
    console.log(event_type, payload, event);
})

// to set a default configuration to use in all future calls for example for a team subdomain
SignRequest.browser.setConfig({subdomain: 'the_subdomain_of_your_team'});

// click on 'Try it!' to execute:
SignRequest.browser.openPopupForDocUrl('https://signrequest.com/static/demo/SignRequestDemoDocument.pdf');

More functionality will be added soon!

Prepare a document

Using the SignRequest frontend web application you have the option 'prepare' a document. This helps the receiver as they can only sign the document at the designated place.

Using the API you can also prepare a document by using tags to specify where a signer needs to add a date, text, checkbox and/or a signature.

Tags need to start with [[ and end with ]]. The tag data is separated by a pipe |. The first letter of the tag represents the tag type and must be one of the following:

  • t for text
  • d for date
  • s for signature
  • c for checkbox

The second piece of data is an integer representing the index of the signer for which this placeholder is intended. For this reason the order at which you add signers to the array matters. If the owner (sender) needs to sign this will always be index 0. Mismatches in the amount of declared placeholders and available signers will be silently ignored. The extra placeholders will not show up if more than the amount of signers OR signers just get an unprepared document to sign when there were no placeholders declared for them.

Examples:

[[s|0                 ]]  # A signature for the first signer OR the owner/sender when they need to sign.
[[c|0                 ]]  # A checkbox placeholder for the first signer
[[d|1                 ]]  # A date input placeholder for the second signer
[[t|2                 ]]  # A text input placeholder for the third signer

The height / width (font size) and the position of the tag in your document matters. Also as you do not want the placeholder tag to show up in the document to avoid this you need to make the font color to match the background. Sign this demo document for and example (the color is left gray to see the tags):

https://signrequest.com/#/?api=v1&who=m&from_email=contact@signrequest.com&doc_url=https%3A%2F%2Fsignrequest.com%2Fstatic%2Fdemo%2FSignRequestTagsExample.pdf

Note that the font chosen can make a difference in the bounding box margins and position. For most fonts the top margin will be bigger as desired. For this reason make sure to leave enough space or double the line height in order for the placeholder to not overlap the line above.

Embed url

Normally SignRequest will send the SignRequest email to signers containing the personal link to sign a document. This is how SignRequest validates an email address and is the preferred way. However, if your application requires a continuous flow (in a salesflow for example) it is possible to generate an embed_url and redirect a signer to that link. Combined with a redirect_url a continuous flow can be achieved.

Doing this moves the responsibility of identifying an email address / user to your application. This also shows in the signing log as SignRequest cannot guarantee that a document is signed by someone having access to an email address.

To generate the embed_url you need to declare the ID of the logged in user in YOUR application in the embed_url_user_id field. This ID will also show in the signing log.

The generated embed_url can only be used until the document is signed. Note that it is perfectly fine to combine signers with and without a generated embed_url. The order field also behaves as you would expect. For example, if the first signer (order = 0) has an embed_url generated and the second (order = 1) not, the second signer will only receive the SignRequest email when the first one has signed.

Integration partner and Teams

If your application requires to create Teams and act on behalf of them you need to become an integration partner. This only grants you access to resources created by your application of the third party Team.

Teams can be created and updated on the Teams resource.

Please contact us to learn more.

Salesforce

The most straight forward way to integrate Salesforce with SignRequest is to use our managed package.

Normally you would use the SignRequest buttons provided in the managed package to create SignRequest documents from Salesforce but if you want to skip that step and create SignRequests using the api (but still sync documents to Salesforce) you can add the following data to a signrequest:

"integration_data": {
    "object_type":"API NAME OF THE (S)OBJECT, e.g. 'Opportunity' or 'CustomObject__c'",
    "uid":"UID OF THE SALESFORCE USER (NOT UUID), e.g. 'https:\\/\\/login.salesforce.com\\/id\\/00D24000000pMDZEA2\\/005240000048zB0AAI'",
    "object_id":"OBJECT ID, e.g. 0062400000MaeNv"
},
"integration":"salesforce"

Caveat: The user of the from_email needs to be a member of the Team that created the signrequest, and the user needs to have a SignRequest account using Salesforce OAuth.

Zapier

Does your app integrate with Zapier? Chances are your digital signatures are just a few clicks away!
Checkout our Zapier integration here: https://signrequest.com/en/digital-electronic-signatures-with-zapier/

Client libraries

The following libraries are not officially supported. Created a client library? Let us know!

More coming soon

Documentation about more advanced usage of the SignRequest API and language specific client libraries is coming soon.

Feel free to contact us at api@signrequest.com for any questions or feature requests.

Examples in Postman

Looking for some examples? Checkout this Postman collection. Not using Postman yet for your (REST) API development? Now is the time! :)



Happy coding!

Subscribe to the API updates newsletter

Subscribe here to receive updates of new API features. To subscribe for disruptions in system health please visit our system health and status page.