What's new in SignHero API


Version 3.0

Released: 27.03.2019
OAuth2 release
What's new?

SignHero API v3 features OAuth2 functionalities by enabling the authorisation code grant type. Now, depending on your needs, it’s possible to manage signature processes through your own SignHero account or do that on behalf of any other user.


Main changes from version 2:

Version 2.0

Will deprecate: 2020
More stability and control over signature processes
What's new?

SignHero API v2 is an improvement release fixing known issues and adding new features to searching through signature processes.


Version 2 documentation:
Download

Version 1.0

Deprecated
The first release

The first release of SignHero API, allowing users to automate signature process management within their own accounts.


Overview


API design principles

All requests and responses are designed using JSON-pure principles.

  • All character sets are UTF-8.
  • All requests use HTTP POST.
  • All requests have MIME type application/json, except document uploads, which have MIME type multipart/form-data.
  • All responses are JSON objects with MIME type application/json, except document downloads, which are binary streams with MIME type application/pdf.

For example:

curl -X POST \ https://api.signhero.io/signatures \
-H 'Content-Type: application/json' \
-d '{
    "action_str": "retrieve",
    "data_type": "signature_flows",
    "trans_map": {
        "auth_key": "YYWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "request_map": {
        "status": "pending"
    }
}'

Authentication


You need an authentication token every time you make a call to SignHero API. SignHero API offers two authorisation grants for your application to authenticate users: Client credentials and Authorisation code.

Authorisation grants - Client credentials


Use this grant when your application needs to access its own processes.

Request an access token


To obtain an access token, present your credentials at the authentication endpoint:

POST /auth HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "create",
    "data_type": "access_token",
    "request_map": {
        "client_id": "signhero.tester@signhero.io",
        "client_secret": "1498b03d760b233673953a11268bb486ab29"
    }
}
{
    "action_str": "created",
    "data_type": "access_token",
    "log_list": [
        {
            "code_key": "200",
            "code_str": "ok",
            "user_msg": "access_token created",
            "level_int": 1,
            "level_str": "info"
        }
    ],
    "trans_map": {
        "auth_key": "YWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    }
}

To make SignHero API calls, add the obtained access token to the auth_key field in the request:

POST /signatures HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "retrieve",
    "data_type": "signature_flow",
    "trans_map": {
        "auth_key": "YWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "request_map": {
        "process_id": "ae3b5221-0272-11e7-a154-46787cfede40"
    }
}

Revoke tokens


To disable your current access token, send a request to the authentication endpoint:

POST /auth HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str" : "delete",
    "data_type" : "access_token",
    "trans_map": {
        "auth_key": "YWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "request_map": {}
}
{
    "action_str": "deleted",
    "data_type": "access_token",
    "log_list": [
        {
            "code_key": "200",
            "code_str": "ok",
            "user_msg": "access_token deleted",
            "level_int": 1,
            "level_str": "info"
        }
    ],
    "response_map": {},
    "trans_map": {}
}

You can also disable all your access tokens with one request:

POST /auth HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "delete",
    "data_type": "access_tokens",
    "trans_map": {
        "auth_key": "YYWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "request_map": {}
}
{
    "action_str": "deleted",
    "data_type": "access_tokens",
    "log_list": [
        {
            "code_key": "200",
            "code_str": "ok",
            "user_msg": "access_tokens deleted",
            "level_int": 1,
            "level_str": "info"
        }
    ],
    "response_map": {},
    "trans_map": {}
}

Authorisation grants - Authorisation code


Use this grant when your application wants to obtain limited access to SignHero API on behalf of users. You'll need to create an OAuth2 application in your SignHero integration settings before getting started.

Create an application


Before using authorisation code grant, you need to create an OAuth2 application.

Log into SignHero portal, open the side menu and select Integrations.

In the integrations list, select Add application.

Fill in application name and optionally description both of which will be present on the user consent page. If you choose to provide a description, explain what your application does and how it is going to use the access granted by the user.

In the following section provide your servers's domain name and at least one redirect URI to which users will be redirected after giving consent. Authorisation code will be added as a query parameter in the redirect URL.

After creating an application you'll see it in the integrations list. The status of the app will be Inactive.

Inactive means that you haven't yet verified the ownership of app's domain. Select your app in the list to proceed.

On the bottom of the application page you will find app's client ID and secret. This is the moment when you should copy the secret and safely store it somewhere. After refreshing the page, the secret won't be visible anymore. If you lost your secret, click on Change secret to generate a new one.

In the Manage redirect URI section you should see your domain name with a warning sign, which means that your domain is not verified. Below the domain name text field you will see instructions on how to verify the domain.

After you've successfully verified your domain, the waring will disappear. In the integrations list, your application will become Active

Congratulations! Now your OAuth2 application can be used to create access tokens using authorisation code grant.

Request an authorisation code


Your application should redirect the user to the authorisation endpoint which will display a consent page.

The authorisation URL should have the following format:

https://signhero.io/oauth2/authorize?client_id={{client_id}}&redirect_uri={{redirect_uri}}&response_type=code&state={{state}}

The parameters in the query:

client_id Your application's client identifier.
redirect_uri The URI to which SignHero will redirect the user after authorisation. This URI must be specified as a valid redirect URI in your application configurations.
response_type The value must be "code".
state A unique string value to prevent CSRF. This value is optional but highly recommended.

If the user approves your request, the user will be redirected to {{redirect_uri}}, and the authorisation code will be part of the redirect URI:

https://example.io/oauth2/callback?&code={{code}}&state={{state}}

If the user choses to cancel, or the request fails, the user will be redirected to {{redirect_uri}} with an error:

https://example.io/oauth2/callback?&error={{error}}&state={{state}}

The parameters in the query:

error One of the following errors described in Error responses.
state A unique string value to prevent CSRF. This value is optional but highly recommended.

Exchange the authorisation code to an access token


Next the authorisation code must be exchanged for an access token that can be used to call SignHero API. To exchange the authorisation code, send a request to the token endpoint:

POST /token HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "create",
    "data_type": "access_token",
    "request_map" : {
        "client_id": "5e5b2260-d3a7-11e8-a608-92030a9483f4",
        "client_secret": "qSHofvOzKlAI7kYCNW3CmleZxmYF5nUiG1RZayDJsM",
        "grant_type": "authorization_code",
        "code": "obweYepSsNTvPTXLlS44umklgq2eArlKm3qPQe0GlXg",
        "redirect_uri": "https://example.io/oauth2/callback"
    }
}

The parameters in the request map:

client_id Your application's client identifier.
client_secret Your application's client secret.
grant_type The value must be "authorization_code".
code The authorisation code.
redirect_uri The URI to which SignHero will redirect the user after authorisation. This URI must be specified as a valid redirect URI in your application configurations.

If the request is valid and authorised, the response includes an access token and refresh token.

{
    "action_str": "created",
    "data_type": "access_token",
    "log_list": [
        {
            "code_key": "200",
            "code_str": "ok",
            "user_msg": "access_token created",
            "level_int": 1,
            "level_str": "info"
        }
    ],
    "response_map": {},
    "trans_map": {
        "access_token": "9YWx0ivNwUtLSHld3H0XfduxdEoPVH0NlmoBM",
        "expires": 1538994375247,
        "refresh_token": "j06Bv5oRTByT5GYiZOuUH4hqm8ZQzaXMdI4XYj1vY"
    }
}

Access tokens expire in 7 days. Refresh tokens never expire.

To make SignHero API calls, add the obtained access token to the access_token field in the request:

POST /signatures HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "retrieve",
    "data_type": "signature_flow",
    "trans_map": {
        "access_token": "9YWx0ivNwUtLSHld3H0XfduxdEoPVH0NlmoBM"
    },
    "request_map": {
        "process_id": "ae3b5221-0272-11e7-a154-46787cfede40"
    }
}

Refresh an access token


To refresh an access token, send a request to the token endpoint:

POST /tokens HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "update",
    "data_type": "access_token",
    "request_map": {
        "client_id": "5e5b2260-d3a7-11e8-a608-92030a9483f4",
        "client_secret": "qSHofvOzKlAI7kYCNW3CmleZxmYF5nUiG1RZayDJsM",
        "grant_type": "refresh_token",
        "refresh_token": "j06Bv5oRTByT5GYiZOuUH4hqm8ZQzaXMdI4XYj1vY"
    }
}

The parameters in the request map:

client_id Your application's client identifier.
client_secret Your application's client secret.
grant_type The refresh token issued to your application.
refresh_token The value must be "refresh_token".

On success the response includes a new access token and refresh token:

{
    "action_str": "updated",
    "data_type": "access_token",
    "log_list": [
        {
            "code_key": "200",
            "code_str": "ok",
            "user_msg": "access_token updated",
            "level_int": 1,
            "level_str": "info"
        }
    ],
    "response_map": {},
    "trans_map": {
        "access_token": "KZ8oUeAYGjz6HSJRlI8O5zaVKRddXW34tbfbsCKqyKk",
        "expires": 1542376889609,
        "refresh_token": "7gzokMZKMbcJtJIe2XULggUAIiEFDIRJuHwFU8cGE"
    }
}

Revoke tokens


To revoke a token, send the following request to the token endpoint:

POST /tokens HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "delete",
    "data_type": "token",
    "request_map": {
        "client_id": "5e5b2260-d3a7-11e8-a608-92030a9483f4",
        "client_secret": "qSHofvOzKlAI7kYCNW3CmleZxmYF5nUiG1RZayDJsM",
        "token": "7gzokMZKMbcJtJIe2XULggUAIiEFDIRJuHwFU8cGE"
    }
}

The parameters in the request map:

client_id Your application's client identifier.
client_secret Your application's client secret.
token The access or refresh token your applications wants to revoke.
{
    "action_str": "deleted",
    "data_type": "token",
    "log_list": [
        {
            "code_key": "200",
            "code_str": "ok",
            "user_msg": "token deleted",
            "level_int": 1,
            "level_str": "info"
        }
    ],
    "response_map": {},
    "trans_map": {}
}

Error responses


On error, the server returns the code_key value 400 (bad_request) and one of the following errors:

access_denied The user or SignHero server denied the request.
invalid_request The request is missing a required parameter, includes an unsupported parameter value or is otheriwse malformed.
invalid_client Client authentication failed.
invalid_grant The provided authorisation grant or token is invalid, expired or revoked.
unauthorized_client The authenticated client is not authorised to use this authorisation grant type.
server_error The server encountered an unexpected condition which prevented it from fulfilling the request.
{
    "action_str": "create_fail",
    "data_type": "access_token",
    "log_list": [
        {
            "code_key": "400",
            "code_str": "bad_request",
            "error": "invalid_client",
            "user_msg": "Invalid client id or secret",
            "level_int": 3,
            "level_str": "error"
        }
    ],
    "response_map": {},
    "trans_map": {}
}

Upload a document


To upload a document post a multipart/form-data request to the documents endpoint. The multi-part request needs to include a payload_data field, which contains the document to sign, and an operation_data field, which contains the JSON-Pure object:

curl -X POST \
    http://api.signhero.io/documents \
    -H 'content-type: multipart/form-data; boundary
        =----WebKitFormBoundary7MA4YWxkTrZu0gW' \
    -F 'operation_data={"action_str":"create","data_type":"document",
        "trans_map ":{"auth_key":"YYWMtGeygaKCEeahbgX148SD2wAAAVipR"},
        "request_map":{}}' \
    -F payload_data=@/Users/signhero/test.pdf

The maximum size for a document is 10MB.

The successful response includes the identifier of the document:

{
    "action_str": "created",
    "data_type": "document",
    "log_list": [
        {
            "code_key": "200",
            "code_str": "ok",
            "user_msg": "document created",
            "level_int": 1,
            "level_str": "info"
        }
    ],
    "trans_map": {
        "auth_key": "YYWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "response_map": {
        "document_id": "d807b62c-08bb-11e7-a142-080027334cc4"
    }
}

Create a signing process


Creating a signing process is a two-part operation: first, upload the documents to sign, second, create the process which signs them.

To create a signing process send a request which lists the identifiers of the uploaded documents as well as the rest of the information about the signing process:

POST /signatures HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "create",
    "data_type": "signature_flow",
    "trans_map": {
        "auth_key": "YYWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "request_map": {
        "title": "My first",
        "locale": "en",
        "signature_invitation": {
            "subject": "Signature invitation",
            "message": "Your signature is requested."
        },
        "documents": [
            "d807b62c-08bb-11e7-a142-080027334cc4"
        ],
        "signers": [
            {
                "name": "SignHero Tester",
                "email": "signhero.tester@signhero.io"
            }
        ]
    }
}

The parameters in the request map:

title A title for the signing process. This value is optional.
locale Specify the language used in the signing pages and emails. Supported locales are en, fi and pl. Defaults to en.
signature_invitation An object presenting the signature invitation.
signature_invitation:subject A custom subject for the email sent to the signers. This value is optional.
signature_invitation:message A custom message in the email sent to the signers. This value is optional.
documents An array containing the identifiers of the documents sent for signature. The maximum number of documents is 20.
signers An array of the signers.
signer:name The name of the signer.
signer:email The email of the signer.
signer:locale Specify the language used in the signing pages and emails. Supported locales are en, fi and pl. Defaults to the locale of the signing process.

The successful response includes the identifiers of the process and signers:

{
    "action_str": "created",
    "data_type": "signature_flow",
    "log_list": [
        {
            "code_key": "200",
            "code_str": "ok",
            "user_msg": "signature_flow created",
            "level_int": 1,
            "level_str": "info"
        }
    ],
    "trans_map": {
        "auth_key": "YYWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "response_map": {
        "process_id": "d7e93169-08bb-11e7-a142-080027334cc4",
        "signers": [
            "2d871e79-0b23-11e7-93dc-42067774ef10"
        ]
    }
}

Retrieve a signing process


Retrieves the details and status of a signing process:

POST /signatures HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "retrieve",
    "data_type": "signature_flow",
    "trans_map": {
        "auth_key": "YYWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "request_map": {
        "process_id": "d7e93169-08bb-11e7-a142-080027334cc4"
    }
}
{
    "action_str": "retrieved",
    "data_type": "signature_flow",
    "log_list": [
        {
            "code_key": "200",
            "code_str": "ok",
            "user_msg": "signature_flow retrieved",
            "level_int": 1,
            "level_str": "info"
        }
    ],
    "trans_map": {
        "auth_key": "YYWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "response_map": {
        "uuid" : "d7e93169-08bb-11e7-a142-080027334cc4",
        "title": "My first",
        "created": 1488807723074,
        "modified": 1488807859249,
        "status": "completed",
        "pending_count": 0,
        "require_strong_auth": false,
        "signature_invitation": {
            "subject": "Signature invitation",
            "message": "Your signature is requested."
        },
        "locale": "en",
        "documents": [
            {
                "uuid": "d807b62c-08bb-11e7-a142-080027334cc4",
                "file_name": "test.pdf"
            }
        ],
        "signers": [
            {
                "uuid": "2d871e79-0b23-11e7-93dc-42067774ef10",
                "name": "SignHero Tester",
                "email": "signhero.tester@signhero.io",
                "locale": "en",
                "embed": false,
                "status": "signed",
                "signed": 1488807859156
            }
        ],
        "completed": 1488807859156
    }
}

The parameters in the response map:

created Time when the signing process was created.
modified Time when the signing process was last modified.
completed Time when the signing process was completed.
canceled Time when the signing process was canceled.
status Status of the signing process:
  • pending: There is pending signatures.
  • completed: All signers have signed.
  • canceled: The signing process has been canceled or someone declined to sign.
  • inactive: Process creation is ongoing. After this the status will be pending or failed.
  • failed: Process creation failed. All failed signing processes are deleted within 24 hours.
pending_count Number of pending signatures.
documents A list of the documents sent for signature.
signers A list of the signers.
signer:status Status of the signer: pending, signed or declined.
signer:signed Time when the signer signed the documents.
signer:declined Time when the signer declined to sign.

Search signing processes


You can retrieve all your signing processes or search them based on their status.

POST /signatures HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "retrieve",
    "data_type": "signature_flows",
    "trans_map": {
        "auth_key": "YYWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "request_map": {
        "status": "pending",
        "scope": "user",
        "limit": 1
    }
}

The parameters in the request map:

status Filter results based on the status field. Accepted values are pending, completed and canceled.
scope Constrain search results to only processes created by the user. Accepted values are user and group. Defaults to user.
limit Number of results to return. The maximum number of results is 1000. Defaults to 10.
cursor Cursor to retrieve the next set of results.
{
    "action_str": "retrieved",
    "data_type": "signature_flows",
    "log_list": [
        {
            "code_key": "200",
            "code_str": "ok",
            "user_msg": "signature_flows retrieved",
            "level_int": 1,
            "level_str": "info"
        }
    ],
    "trans_map": {
        "auth_key": "YYWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "response_map": {
        "signature_flows": [
            {
                "uuid" : "d7e93169-08bb-11e7-a142-080027334cc4",
                "title": "My first",
                "created": 1488799050744,
                "modified": 1488799050744,
                "status": "pending",
                "pending_count": 1,
                "locale": "en",
                "documents": [
                    {
                        "uuid": "d807b62c-08bb-11e7-a142-080027334cc4",
                        "file_name": "test.pdf"
                    }
                ],
                "signers": [
                    {
                        "uuid": "2d871e79-0b23-11e7-93dc-42067774ef10",
                        "name": "SignHero Tester",
                        "email": "signhero.tester@signhero.io",
                        "locale": "en",
                        "embed": false,
                        "status": "signed",
                        "signed": 1488807859156
                    }
                ]
            }
        ],
        "cursor": "OikKAfqAMqMjU20wSDdHlwZUtzaWduX3Byb2Nlc3P7gDHS-w=="
    }
}

The parameters in the response map:

cursor Cursor to retrieve the next set of results.
signature_flows Found signing processes.

Cancel a signing process


A signing process that has not been completed can be canceled. Signers will not be able to review and sign the documents anymore.

POST /signatures HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "update",
    "data_type": "signature_flow",
    "trans_map": {
        "auth_key": "YWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
        "request_map": {
            "process_id": "ae3b5221-0272-11e7-a154-46787cfede40",
            "cancel": true
    }
}
{
    "action_str": "updated",
    "data_type": "signature_flow",
    "log_list": [
        {
            "code_key": "200",
            "code_str": "ok",
            "user_msg": "signature_flow updated",
            "level_int": 1,
            "level_str": "info"
        }
    ],
    "response_map": {},
    "trans_map": {
        "auth_key": "YWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    }
}

Delete a signing process


A signing process that has been completed or canceled can be deleted from search results.

POST /signatures HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "delete",
    "data_type": "signature_flow",
    "trans_map": {
        "auth_key": "YWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "request_map": {
        "process_id": "ae3b5221-0272-11e7-a154-46787cfede40"
    }
}
{
    "action_str": "deleted",
    "data_type": "signature_flow",
    "log_list": [
        {
            "code_key": "200",
            "code_str": "ok",
            "user_msg": "signature_flow deleted",
            "level_int": 1,
            "level_str": "info"
        }
    ],
    "response_map": {},
    "trans_map": {
        "auth_key": "YWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    }
}

Download a document


To get a copy of the current document make a download request to the documents endpoint:

POST /documents HTTP/1.1
Host: api.signhero.io
Content-Type: application/json

{
    "action_str": "retrieve",
    "data_type": "document",
    "trans_map": {
        "auth_key": "YYWMtGeygaKCEeahbgX148SD2wAAAVipR17t2Xygd71iJDLWO"
    },
    "request_map": {
        "document_id": "d807b62c-08bb-11e7-a142-080027334cc4"
    }
}

The successful response is a binary stream with MIME type application/pdf.

The downloaded document will always be the current version of it which may have all, some or none signatures depending on how many people have signed already.