API Usage

The Adobe Sign API allows you to quickly build client-side applications that can utilize the signing functionalities offered by Adobe Sign. This guide contains the most common scenarios in which you can use the API.

Using the Adobe Sign REST APIs, you can build elegant and scalable client-side applications in any scripting language that supports REST-based API calls. This section provides information on the API endpoint, request headers, request body, and the response.

A 3-step basic signing workflow involves:

Send for Signing (Create an Agreement)

Your CRM system or document management system can send/upload documents for signing, either automatically or through user-initiated actions. When the document gets signed by all the parties, a PDF copy of the signed document(agreement) can be retrieved by your application.

_images/sign_devguide_1.png

While getting the authorization code from the Adobe Sign service, you also received the API access point as part of a query parameter (See OAuth token exchange)

https://myserver.com/?
    code=CBNCKBAThIsIsNoTaReAlcs_sL4K32wCzs4N&
    api_access_point=https://api.na1.echosign.com/&
    web_access_point=https://secure.na1.echosign.com/

For all future service calls, Adobe Sign sends the requests to this access point.

Upload a document

To upload a PDF document for signing, send a POST request to the transientDocuments endpoint. This is a multipart request consisting of filename, MIME type, and the file stream. You will get back an ID as a response that uniquely represents the document. Your application needs to specify the recipients and other sending options required for sending the document for signing. Your application can also specify a callback URL that will be used by Adobe Sign to notify when the signature process is complete.

POST /api/rest/v6/transientDocuments HTTP/1.1
Host: api.na1.echosign.com
Authorization: Bearer MvyABjNotARealTokenHkYyi
Content-Type: multipart/form-data
Content-Disposition: form-data; name=";File"; filename="MyPDF.pdf"

<PDF CONTENT>

You will get the following JSON body containing the transientDocumentId that will uniquely represent the uploaded document:

{
    "transientDocumentId":"3AAABLblqZhBVYbgJbl--NotArEaLID_zjaBYK"
}

The document uploaded through this call is termed as a transient document since it is available only for 7 days after the upload.

You can only upload one file at a time through this request.

TRY IT OUT

Send the document

Once you have uploaded the document, send the document to all the related parties for signing. For this to happen, you need to create an agreement.

For creating an agreement, send a POST request to the /agreements endpoint with the following JSON body:

POST /api/rest/v6/agreements HTTP/1.1
Host: api.na1.echosign.com
Authorization: Bearer 3AAABLblNOTREALTOKENLDaV
Content-Type: application/json

{
    "fileInfos": [{
        "transientDocumentId": "<copy-transient-from-the-upload-document-step>"
    }],
    "name": "MyTestAgreement",
    "participantSetsInfo": [{
        "memberInfos": [{
            "email": "signer@somecompany.com"
        }],
        "order": 1,
        "role": "SIGNER"
    }],
    "signatureType": "ESIGN",
    "state": "IN_PROCESS"
}

Replace the value for the following attributes with the correct values:

Attribute

Description

transientDocumentId

The unique ID representing the uploaded document.

name

The name of the agreement.

email

Recipient’s email address.

signatureType

The type of signature you would like to request. The possible values are ESIGN and WRITTEN.

order

Index indicating the position at which this signing group needs to sign. Signing group to sign at first place is assigned 1 as index.

role

Role of the participant set. The possible values are: SIGNER, APPROVER, ACCEPTOR, CERTIFIED_RECIPIENT, FORM_FILLER or DELEGATE_TO_SIGNER, DELEGATE_TO_APPROVER, DELEGATE_TO_ACCEPTOR, DELEGATE_TO_CERTIFIED_RECIPIENT, DELEGATE_TO_FORM_FILLER, or SHARE.

state

The state in which the agreement should land. The possible values are AUTHORING, DRAFT, or IN_PROCESS. You can use a) DRAFT to incrementally build the agreement before sending out, b) AUTHORING to add or edit form fields in the agreement, c) IN_PROCESS to immediately send the agreement. You can use the PUT /agreements/{agreementId}/state endpoint to transition an agreement between the above-mentioned states. An allowed transition would follow this sequence: DRAFT -> AUTHORING -> IN_PROCESS -> CANCELLED.

You will get the following response containing the id:

{
    "id": "<an-adobe-sign-generated-id>"
}

The returned agreementId must be used to refer to the agreement in all subsequent API calls. This ID must be used to retrieve up-to-date status of the agreement, either by polling or when Adobe Sign notifies your application of any status change.

TRY IT OUT

Check the Document Signing Status

Adobe Sign can return the current status of the agreement and a complete history of events that have happened on that particular agreement. The simplest mechanism is for your application to provide a webhook URL when sending the document for signature. Adobe Sign will then ping your webhook with the appropriate Webhook Events whenever the status of the agreement changes.

_images/sign_devguide_2.png

You can also get the current status of an agreement by sending a GET request to /agreements/{agreementid}:

GET /api/rest/v6/agreements/3AAABLblqZNOTREALAGREEMENTID5_BjiH HTTP/1.1
Host: api.na1.echosign.com
Authorization: Bearer 3AAANOTREALTOKENMS-4ATH

You need to provide your access token in the Authorization header and the agreementId in the API call itself. You will get the following JSON response:

{
  "id": "<an-adobe-sign-generated-id>",
  "name": "MyTestAgreement",
  "participantSetsInfo": [{
    "memberInfos": [{
      "email": "signer@somecompany.com",
      "securityOption": {
        "authenticationMethod": "NONE"
      }
    }],
    "role": "SIGNER",
    "order": 1
  }],
  "senderEmail": "sender@somecompany.com",
  "createdDate": "2018-07-23T08:13:16Z",
  "signatureType": "ESIGN",
  "locale": "en_US",
  "status": "OUT_FOR_SIGNATURE",
  "documentVisibilityEnabled": false
}

By default, the webhook URL is called whenever an event involving a particular transaction occurs in Adobe Sign. The webhook event includes the ID of the agreement whose status has changed, the current status of the agreement, and information on the event that resulted in the callback. Your application logic can evaluate the received status and decide whether to perform an action in the calling system.

In addition to HTTPS GET, Adobe Sign also alternatively supports PUT for receiving events about the signature process. Included in the request will be the completed signed PDF. Adobe Sign uses an PUT request to return the signed PDF. Please ensure that your application can correctly handle such a request. Please contact Adobe Support or your assigned Client Success Manager to get your account configured to receive PUT events.

The second mechanism to reflect the most current or up-to-date status of an agreement sent for signature is for your application to periodically poll Adobe Sign regarding the agreement’s status. The upside of polling is that it can be used in cases where your calling application is behind your firewall and not accessible from the Internet, thus enabling Adobe Sign to complete a callback. The down side of polling is that you have to create a scheduling mechanism within your application to periodically query the status of all documents that were not yet signed, check whether the document’s status has changed, and update your system accordingly. If you choose to use polling, we recommend you have different policies based on document “age”. In other words, you would reduce the frequency of polling for documents not signed after a certain number of days.

TRY IT OUT

Send Reminders

A signing reminder can be sent to all the signers if they have not signed the agreement. When you send a reminder, the signers will get the same notification email that was originally sent.

_images/sign_devguide_3.png
POST /api/rest/v6/agreements/{agreementId}/reminders HTTP/1.1
Host: api.na1.echosign.com
Authorization: Bearer 3AAABLblNOTREALTOKENLDaV
Content-Type: application/json
{
  "recipientParticipantIds": [
    "<id of a participant>."
  ],
  "nextSentDate": "< The date when the reminder is scheduled to be sent next.>",
  "status": "< valid status of reminder (ACTIVE)>"
}

Note that you need to provide the agreementId in the request URL. You will get the following response from the server:

{
   id: <An identifier of the reminder resource created on the server>
}

TRY IT OUT

Download the Agreement

Once an agreement is signed, your application can retrieve the signed copy of the PDF and store that within your application.

_images/sign_devguide_4.png

The signed agreement can also be retrieved by sending a GET request to /agreements/{agreementId}/combinedDocument. This will return a single combined PDF document for the documents associated with the agreement. To retrieve any supporting document, you can send a GET request to /agreements/{agreementId}/documents. This will return the IDs of all the main and supporting documents of an agreement.

The returned document ID can be used in the /agreements/{agreementId}/documents/{documentId} call to retrieve the file stream of a document of the agreement. Depending on your application, you can also retrieve the form field data that your signer may have filled in to the document when signing the document by sending a GET request to /agreements/{agreementId}/formData. The data can be used to update your calling application with the information provided by the signer during signing.

Send the following GET request to retrieve the signed agreement:

GET /api/rest/v6/agreements/3AAA5NOTREALIDiH/combinedDocument HTTP/1.1
Host: api.na1.echosign.com:443
Authorization: Bearer 3AAABLblqZhB9BF

The response body will contain the content of the PDF file, which you can save locally through your application.

Note that the agreement can be downloaded even before it gets signed. Provide the versionId attribute when invoking GET /agreements/{agreementId}/combinedDocument/ to get the correct version of the agreement. For example, when the agreement is sent to two entities for signing, and when only one entity signs, the document can still be downloaded. If the versionId is not specified, the document in the latest state is returned.

TRY IT OUT

Create a Widget

To create a widget through the API, you must first call /transientDocuments, then send a POST request to upload the document. This is a multipart request consisting of filename, MIME type, and the file stream. The returned transientDocumentId is to be used to refer to the document in the widget creation call (/widgets, POST). The API endpoint, in addition to the widget key, returns an embed-code, which can be used for embedding the widget within your application, as well as a URL at which the widget gets hosted. The URL can be posted within your application for users to navigate to for signing a document.

POST /api/rest/v6/widgets HTTP/1.1
Host: api.na1.echosign.com
Authorization: Bearer 3AAABLblqZNotRelaTOKEN
Content-Type: application/json
{
    "name": "MyTestWidget",
    "widgetParticipantSetInfo": {
        "memberInfos": [{
            "email": ""
        }],
    "role": "A valid role of the widget signer (SIGNER/APPROVER)"
    },
    "state": "A valid state in which the widget should land (ACTIVE/AUTHORING/DRAFT)"
}

You will get the following JSON response:

{
    id: <The unique identifier of widget which can be used to retrieve the data entered by the signers.>
}

Now, the Widget URL can be circulated to the parents for signing. At any time, to get information about the Widget, send a GET request to /widgets/{widgetId}.

GET /api/rest/v6/widgets/3AAANotTheRealID6o HTTP/1.1
Host: api.na1.echosign.com

You will get a JSON response containing details about the widget, including participants’ information and status.

You can also send a GET request to /widgets/{widgetId}/formData to retrieve the data entered (by the parents) in the document when it got signed.

Each time a widget is signed by a person, a separate instance of a document gets created. To get the agreements created using the widget, call /widgets/{widgetID}/agreements GET where widgetID is the key returned by the service while creating the widget. To retrieve the data filled by the users at the time of signing the widget, call GET /widgets/{widgetID}/formData. The service returns data in comma-separated value (CSV) file format. The first line includes the column header names, and each row represents a distinct instance of the widget.

TRY IT OUT

Get the Signing URL

When the agreement is ready for signing, invoke GET /agreements/{agreementId}/signingUrls to get the signing URL:

GET /api/rest/v6/agreements/3AANotRealIDQN8_gg/signingUrls HTTP/1.1
Host: api.na1.echosign.com
Authorization: Bearer 3AAABLblqZNotRelaTOKEN

You will get the following JSON response containing the signing URL:

{
  "signingUrlSetInfos": [
    {
      "signingUrls": [
        {
          "email": "FJ@MYCOMPANY.COM",
          "esignUrl": "https://secure.na1.echosign.com/public/apiesign?pid=CBFNotTheRealIDw3w*"
        }
      ]
    }
  ]
}

Getting the signing URL becomes useful for scenarios involving in-person signing. Load the signing URL in a browser window on a mobile device and get the agreement signed in-person.

TRY IT OUT

API Throttling

To prevent your API from being overwhelmed by too many requests, Adobe throttles requests to your API.

When a request is throttled, the client will receive an HTTP 429 “Too Many Requests” response with an error message appropriate to the request. When a request gets back an HTTP 429 response, it means the user has consumed over the limit of allowed resources in a certain period of time. It could be a violation of per-minute, -hour, or -day limit. The user will be allowed to make more requests in the next minute, hour, or day (depending on which threshold was crossed).

Each request made to Adobe Sign is evaluated based on the amount of system resources it will consume. Different parameters passed to the same endpoint might contribute a different amount of resource consumption. Your service package (small business, business, enterprise) directly influences your transaction rate. Higher tiers of service have higher throttle thresholds.

REST API Response

{
"code":"THROTTLING_TOO_MANY_REQUESTS",
"message":"<error_message_with_wait_time> (apiActionId=<api_action_id>)"
"retryAfter": <wait_time_in_seconds>
}

Also, a Retry-After HTTP header will be added into the response (see RFC-7231 Section 7.1.3)

Retry-After: <wait_time_in_seconds>

is the minimum time in seconds the client must wait until it can make the next request. When the retryAfter timer expires, the client’s resource count is reset to 0 for the over-limit threshold. Therefore, the client can send the request again and it should go through without being blocked.

Steps to take when throttled

It is recommended that developers design workflows that can handle the Http 429 exceptions gracefully and use the retry-time from either the response body or from the “Retry-After” header to recover from such errors.

Adobe Sign v6 REST API Enhancements

This page is a comprehensive guide for developers who are looking to plug Adobe Sign Version 6 REST APIs in their solutions. We list out all the enhancements and new features that are part of the v6 Adobe Sign APIs. To facilitate developers who are already using older versions of our APIs in migrating to Version 6, we have tabulated the v6 APIs against their closest counterparts in previous versions in the API Change Log. In the change log, we have documented enhancements, features, and any changes from the prior version. In addition to the information compiled here, you can also refer to the Adobe Sign API Reference to get a quick reference for the Adobe Sign APIs. This page lists all our APIs in a easily discoverable format and lets you try them out without having to write any code!

Enhancements

Pagination Support

Existing Adobe Sign APIs return the entire list of resources (agreements, widgets, or library documents) that a user has in a GET call. For some users with a large number of transactions this resource list becomes too big for consumption. The v6 APIs have introduced pagination support to all these resources with a client-configurable page size. This will be especially useful to our mobile clients and integrations who are constrained by their consumption capacity. This sample shows pagination in a request and response:

Sample Request

GET https://api.na1.echosign.com:443/api/rest/v6/agreements?pageSize=50

Sample Response

{
    "userAgreementList": [{
      "displayDate": "2017-04-17T06:07:19-07:00",
      "displayUserSetInfos": [
        {
          "displayUserSetMemberInfos": [
            {
              "company": "Adobe",
              "email": "adobe.sign.user@adobe.com",
              "fullName": "AdobeSign User"
            }
          ]
        }
      ],
      "esign": true,
      "agreementId": "3AAABLblqZhDqIcUs4nFgivebIUdzuZyBrjO_VP_hHDhkrGhXxKuQ5Hi7C07vRbNzxP9TdTdRHzHdQLDsPJrjfXEuKe7jjEAl",
      "latestVersionId": "3AAABLblqZhACieamyoCl7qNWZTaU3WaoY3a9BL7-09sosH88HyRFfGmYc91jpQk-LXLVGlgEudioxgPlCprAScifamX16-QD",
      "name": "SampleAgreement",
      "status": "SIGNED"
    },
    {...},
    .
    .
    .],
    "page": {
        "nextCursor": "qJXXj2UAUX1X9rTSqoUOlkhsdo*"
    }
}

The subsequent GET /resources calls would just need to add nextCursor as query param in the URL for fetching the next set of resources.

Sample Request

GET https://api.na1.echosign.com:443/api/rest/v6/agreements?pageSize=50&cursor=qJXXj2UAUX1X9rTSqoUOUOlkhsdo*

Constant IDs

Our Partners and Integrators have requested that the identifiers remain constant in the lifetime of a resource. This is because they tend to store these resource IDs and do a match later, which can break with ID changes. The v6 APIs address this by ensuring that IDs stay constant through time and across all API callers for a given resource. This will enable clients to build their own metadata associated with an Adobe Sign resource ID.

Identifiers are forward-compatible: older identifiers will continue working in v6 Sign APIs. However, new identifiers generated through v6 APIs will only be compatible with Adobe Sign v6 or any higher version.

ETag support

Polling on a resource is a common operation; for instance, in the case of agreements, where a client application is attempting to check the latest status. The v6 REST APIs significantly optimize this by adding support for an ETag, which will only fetch the full body response if the resource has been modified. This saves the client from loading the same response as well as its unnecessary parsing.

In addition, this also helps to resolve conflicts in the case of concurrent update operations by only allowing the updates with the ETag of the latest version of the resource in their request header (If-match). This example explains the functioning of ETags in detail:

Sample GET Operation (ETag in Request Header)

URI : GET https://api.na1.echosign.com:443/api/rest/v6/agreements/CBJCHBCAABAAQonMXhG-V6w-rheRViZNFGxmCgEEf3k0

Headers : Authorization: Bearer <access-token>
          Accept: */*
          Accept-Encoding: gzip, deflate, br
          Accept-Language: en-US,en
          If-None-Match: CBJCHBCAABAA-mdO9PI7WFmHNkXFUIEYIOYGrnM3vVK_

The above request will result in a 304(Resource Not Modified) HTTP response if the ETag provided in the If-None-Match header represents the latest version of the resource. Otherwise, the response body will include the queried resource in the usual format, along with an ETag representing the fetched version of the resource in the response header.

The response header below represents the second scenario, in which the resource has been modified prior to the request (notice the ETag as one of the headers).

Response Header

Date: Mon, 12 Feb 2018 09:45:24 GMT
Server: Apache
ETag: D27e5290dc3a748068e42a59f4dfc6f6b1d5eaba1
Content-Length: 661
  ...
Keep-Alive: timeout=15, max=200
Connection: Keep-Alive
Content-Type: application/json;charset=UTF-8

Update or delete operations will have a similar workflow. The clients are required to provide the ETag of the resource version that they want to update in the If-Match request header. The update will only be successful if the ETag in the request header represents the latest version of the resource on the server. Otherwise, this will result in a 412 (Precondition Failed) response. In this example, we are trying to update the status of the agreement fetched above:

Sample PUT Operation (ETag In Request Header)

URI : PUT  https://api.na1.echosign.com:443/api/rest/v6/agreements/CBJCHBCAABAAQonMXhG-V6w-rheRViZNFGxmCgEEf3k0/status

Headers : Authorization: Bearer <access-token>
          Accept: */*
          Accept-Encoding: gzip, deflate, br
          Accept-Language: en-US,en
          If-Match: CBJCHBCAABAA-mdO9PI7WFmHNkXFUIEYIOYGrnM3vVK_

The response below indicates that we are trying to update an older version (observe the ETag in the request) of this resource. Along with this response body, the response header contains the HTTP status code 412(Precondition Failed).

Sample PUT Operation (ETag In Request Header)

{
    "code": "RESOURCE_MODIFIED",
    "message": "Resource is already modified with newer version"
}

The ETag value required to be passed in any PUT or DELETE API can be obtained from a corresponding GET operation on the same entity. The table below mentions these modification (PUT or DELETE) APIs along with the corresponding GET APIs that provides the ETag value for these modification requests.

Update/Deletion API

Corresponding GET endpoint

PUT /agreements/{agreementId}

GET /agreements/{agreementId}

POST /agreements/{agreementId}/formFields

GET /agreements/{agreementId}/formFields

PUT /agreements/{agreementId}/formFields

GET /agreements/{agreementId}/formFields

PUT /agreements/{agreementId}/formFields/mergeInfo

GET /agreements/{agreementId}/formFields/mergeInfo

PUT /agreements/{agreementId}/members/participantSets/{participantSetId}

GET /agreements/{agreementId}/members/participantSets/{participantSetId}

PUT /agreements/{agreementId}/state

GET /agreements/{agreementId}

DELETE /agreements/{agreementId}/documents

GET /agreements/{agreementId}/documents

PUT /libraryDocuments/{libraryDocumentId}

GET /libraryDocuments/{libraryDocumentId}

PUT /libraryDocuments/{libraryDocumentId}/state

GET /libraryDocuments/{libraryDocumentId}

PUT /widgets/{widgetId}

GET /widgets/{widgetId}

PUT /widgets/{widgetId}/state

GET /widgets/{widgetId}

PUT /megaSigns/{megaSignId}/state

GET /megaSigns/{megaSignId}

DELETE /users/{userId}/signatures/{signatureId}

GET /users/{userId}/signatures/{signatureId}

PUT /webhooks/{webhookId}

GET /webhooks/{webhookId}

PUT /webhooks/{webhookId}/state

GET /webhooks/{webhookId}

DELETE /webhooks/{webhookId}

GET /webhooks/{webhookId}

GET, PUT, POST consistency

In building the Adobe Sign v6 APIs, we have enabled more simplicity in the design of client applications by creating consistency across GET, POST, and PUT operations in each API, thereby enabling clients to reuse the same model across these APIs. For reference see the agreement model in the (POST|PUT|GET) /agreements API.

Performance improvements

The creation and update APIs are now asynchronous, which significantly improves their response time. This frees clients from waiting on these operations and they can move on to next steps in their workflow.

Clients should now poll on the status of the newly created resource before certain sub-resource operations, such as documents in the case of agreements. For example, in case of agreement creation, the initial status is DOCUMENTS_NOT_YET_PROCESSED, which is updated to the intended status such as OUT_FOR_SIGNATURE once all the background tasks are successfully completed.

Asynchronous API’s

One of the significant change in v6 API’s has been to make resource intensive operations asynchronous to a larger extent. This reduces waiting/blocking time for clients in most of the scenarios. For example, in v5, workflows such as sending an agreement, creating megasign or a widgets etc. has significantly larger response time than v6. In v6, the API execution time has been improved by making the time intensive processes asynchronous and executing them in the background. Adobe Sign provides status/error codes in the GET api’s for clients to know the status of these background processes and decide on their next steps accordingly. The clients can poll on these GET api’s or move on to new resource creation/workflow depending on their use case.

Refer the lists below all the asynchronous api’s and their corresponding GET api’s which clients can poll on till polling condition holds true.

Asynchronous API: POST /agreements

GET API To Poll: GET /agreements/{agreementId}

GET Response Body: {
… “status”: “” }

GET HTTP Status: 200

Polling Condition On GET: status == DOCUMENTS_NOT_YET_PROCESSED


Asynchronous API: POST /agreements

GET API To Poll: GET /agreements/{agreementId}/signingUrls

GET Response Body: { “code”: “AGREEMENT_NOT_SIGNABLE”, “message”: “The agreement is not currently waiting for anyone to sign it.” }

GET HTTP Status: 404

Polling Condition On GET: status == DOCUMENTS_NOT_YET_PROCESSED


Asynchronous API: PUT /agreements/{agreementId}/state

GET API To Poll: GET /agreements/{agreementId}

GET Response Body: { … “status”:“” }

GET HTTP Status: 200

Polling Condition On GET: status != IN_PROCESS


Asynchronous API: POST /widgets

GET API To Poll: GET /widgets/{widgetId}

GET Response Body: { … “status”: “” }

GET HTTP Status: 200

Polling Condition On GET: status == DOCUMENTS_NOT_YET_PROCESSED


Asynchronous API: PUT /widgets/{widgetId}/state

GET API To Poll:: GET /widgets/{widgetId}

GET Response Body: { … “status”:“” }

GET HTTP Status: 200

Polling Condition On GET: status == DOCUMENTS_NOT_YET_PROCESSED


Asynchronous API: POST /megaSigns

GET API To Poll: GET /megaSigns/{megaSignId}/agreements

GET Response Body: { “megaSignList” : [ … {}, …],

page”: { … } }

GET HTTP Status: 200

Polling condition on GET: megaSignList.size() != Requested Number of Child Agreements


Hosted Signing

One of the common workflows used by Adobe Sign clients is to create an agreement and get the corresponding signing url. Since, the agreement creation is asynchronous the clients needs to poll on GET /agreements/{agreementId}/signingUrls for fetching signing url. The sample code below implements this use case.

Polling For Signing Url

var APIConfig = {
    "apiBaseUrl": "<base-uri-for-client>",
    "accessToken": "Bearer <valid-access-token>",
    "transientDocumentId": "<valid-transient-document-id>"
}

function getSigningUrlForAsyncAgreementCreation() {

    var getSigningUrl = function(agreementId) {
        var apiUrl = APIConfig.apiBaseUrl + "/api/rest/v6/agreements/" + agreementId + "/signingUrls";
        jQuery.ajax({
            url: apiUrl,
            type: "GET",
            beforeSend: function(xhr) {
                xhr.setRequestHeader('Authorization', APIConfig.accessToken);
            },
            success: function(result, status, request) {
                // API execution is successful, the signing url is present in result
            },
            error: function(result, status, request) {
                // If error occurs with HTTP status 404 and error code is AGREEMENT_NOT_SIGNABLE the background processes in agreement creation has not completed.
                // Re attempt API after polling time period.
                if(status === 404 && result.code == "AGREEMENT_NOT_SIGNABLE") {
                    window.setTimeout(function() {
                        getSigningUrl(agreementId);
                    }, 500);
                }
                // In all other cases, there is a genuine failure in retrieving signing url. Parse error code and message for more detail.
            }
        });
    }

    var createAgreementAsynchronously = function() {

        var agreementCreationRequest = {
            "fileInfos": [{
                "transientDocumentId": APIConfig.transientDocumentId
            }],
            "name": "Asynchronous Agreement",
            "participantSetsInfo": [{
                "memberInfos": [{
                    "email": "<signer-email>"
                }],
                "order": 1,
                "role": "SIGNER"
            }],
            "signatureType": "ESIGN",
            "state": "IN_PROCESS"
        }

        agreementCreationRequest = JSON.stringify(agreementCreationRequest);

        jQuery.ajax({
            url: APIConfig.apiBaseUrl + "/api/rest/v6/agreements",
            type: "POST",
            beforeSend: function(xhr) {
                xhr.setRequestHeader('Authorization', APIConfig.accessToken);

            },
            contentType: "application/json",
            data: agreementCreationRequest,
            success: function(result, status, request) {
                // Call GET /agreements/{agreementId}/signingUrls api after 500ms
                window.setTimeout(function() {
                    getSigningUrl(result.id);
                }, 500);
            }
        });
    }

    createAgreementAsynchronously();
}

getSigningUrlForAsyncAgreementCreation();
Simple Agreement Creation

Some operations on a newly created agreement like downloading agreement document are not allowed until all the background processes in creating agreement is completed. The GET /agreements/{agreementId} API provides the status of the agreement on which the client can poll before performing such operations. Refer the sample code below for more details.

Polling For Signing URL

var APIConfig = {
    "apiBaseUrl": "<base-uri-for-client>",
    "accessToken": "Bearer <valid-access-token>",
    "transientDocumentId": "<valid-transient-document-id>"
}

function getAgreementInfoForAsyncAgreementCreation() {
    var getAgreementInfo = function(agreementId) {
        var apiUrl = APIConfig.apiBaseUrl + "/api/rest/v6/agreements/" + agreementId;
        jQuery.ajax({
            url: apiUrl,
            type: "GET",
            beforeSend: function(xhr) {
                xhr.setRequestHeader('Authorization', APIConfig.accessToken);
            },
            success: function(result, status, request) {
                /**
                Parse API result for agreement status. If the agreement status is DOCUMENTS_NOT_YET_PROCESSED then, all the background processed in agreement creation is not complete yet.
                */
                if(result.status == "DOCUMENTS_NOT_YET_PROCESSED") {
                    window.setTimeout(function() {
                        getAgreementInfo(agreementId);
                    }, 500);
                }
                else {
                    // All the background tasks in agreement creation is completed.
                }
            },
            error: function() {
                // API execution failed.
            }
        });
    }

    var createAgreementAsynchronously = function() {
        var agreementCreationRequest = {
            "fileInfos": [{
                "transientDocumentId": APIConfig.transientDocumentId
            }],
            "name": "Asynchronous Agreement",
            "participantSetsInfo": [{
                "memberInfos": [{
                    "email": "<signer-email>"
                }],
                "order": 1,
                "role": "SIGNER"
            }],
            "signatureType": "ESIGN",
            "state": "IN_PROCESS"
        }

        agreementCreationRequest = JSON.stringify(agreementCreationRequest);

        jQuery.ajax({
            url: APIConfig.apiBaseUrl + "/api/rest/v6/agreements",
            type: "POST",
            beforeSend: function(xhr) {
                xhr.setRequestHeader('Authorization', APIConfig.accessToken);

            },
            contentType: "application/json",
            data: agreementCreationRequest,
            success: function(result, status, request) {
                // Call GET /agreements/{agreementId} api after 500ms
                window.setTimeout(function() {
                    getAgreementInfo(result.id);
                }, 500);
            }
        });
    }

    createAgreementAsynchronously();
}
 getAgreementInfoForAsyncAgreementCreation();
Polling Frequency

The polling frequency can vary from clients to clients depending on their use case. Clients using large files in agreement creation are expected to keep time between subsequent polling calls more compared to the scenarios where the agreement files uploaded are small. The table below can be referred as a general guideline by clients to determine their polling frequency.

File Size

Polling Time Period

< 100KB

500 ms

> 100KB and < 2 MB

1s

> 2MB

2s

Authorization header

The Adobe Sign API accepts an authorization token in the access-token header; however, from v6 onwards we will be migrating to the standard Authorization header. The Authorization header will hold the user’s authorization token in this format:

Authorization: Bearer <access-token>

Clients can continue using their older access token, but in the authorization header using this format.

Features

Agreement sharing

This feature enables users associated with an agreement to share the agreement at any point of time through Adobe Sign APIs. This feature brings the agreement sharing capability in Adobe Sign web app and Adobe Sign APIs at par. The POST /agreements/{agreementId}/members/share API exposes the agreement sharing feature.

Authoring APIs

The authoring APIs are a set of APIs that allow a user to author the documents of an agreement before sending them out. The authoring operation here refers to creating, editing or placing form fields along with their configurations (assignee, conditions, data type, and more) in the agreement documents. The v6 APIs have these capabilities and a client can now leverage these APIs to create their own agreement authoring experience. The table below lists the APIs in this set along with the functionality that they provide.

Authoring API

Functionality

POST /agreements/{agreementId}/formFields

Adds forms to an agreement from the given template. The response would contain the information of all the newly added form fields.

GET /agreements/{agreementId}/formFields

Retrieves all the form fields present in an agreement.

PUT /agreements/{agreementId}/formFields

Updates and configures(say location, default value, background, etc.) the present form fields in the agreement documents.

Document visibility

The new document visibility feature allows senders to control the exposure of agreement documents for specific participants through APIs. This empowers clients to hide from participants those parts of agreements that are irrelevant to them. The agreement creation request below hides the second document of the agreement from the first participant.

Document Visibility Example

{
    "fileInfos": [{
            "transientDocumentId": "<first-transient-document>"
        },
        {
            "transientDocumentId": "<second-transient-document>"
        }
    ],
    "name": "Custom Agreement",
    "participantSetsInfo": [{
            "memberInfos": [{
                "email": "firstSigner@adobe.com"
            }],
            "name": "First Signer",
            "visiblePages": [
                "0", "1"
            ],
            "order": 1,
            "role": "SIGNER"
        },
        {
            "memberInfos": [{
                "email": "secondSigner@adobe.com"
            }],
            "name": "Second Signer",
            "visiblePages": [
                "0", "1", "2"
            ],
            "role": "SIGNER",
            "order": "2"
        }
    ],
    "signatureType": "ESIGN",
    "state": "IN_PROCESS"
}

Draft

The v6 APIs provides the capability for an incremental creation of a resource by introducing the concept of “DRAFT”. The incremental creation of any resource is really helpful, especially when it is constituted of many complex components. Draft is a temporary or primitive stage of the final intended resource that can be updated in steps to create the final resource.

This example illustrates a stepwise creation of an agreement:

Step 1: POST /agreements to create an initial draft

{
    "fileInfos": [{
        "transientDocumentId": "<a-valid-transient-resource-id>"
    }],
    "name": "Draft",
    "signatureType": "ESIGN",
    "state": "DRAFT"
}

The step above creates a draft. Notice that we have not assigned any participant to this agreement yet.

Step 2: PUT /agreements/{agreementId} to complete this draft

{
    "fileInfos": [{
        "transientDocumentId": "<a-valid-transient-resource-id>"
    }],
    "name": "Agreement",
    "participantSetsInfo": [{
        "memberInfos": [{
            "email": "signer@adobe.com"
        }],
        "role": "SIGNER",
        "order": "1"
    }],
    "signatureType": "ESIGN",
    "state": "DRAFT"
}

Notice the addition of a participant and an update in the name field. This step can be iterated any number of times until we have all the data needed to create the agreement.

The next step finalizes the draft into an agreement.

Step 3: PUT /agreements/{agreementId}/state to complete this draft

{
  "state": "IN_PROCESS"
}

Notes management

The v6 Adobe Sign APIs has endpoints to manage notes in an agreement. Clients can add notes to an agreement and retrieve them using these API’s. The table below lists all these APIs and their operation.

Notes API

Functionality

GET /agreements/{agreementId}/me/note

Retrieves the latest note on an agreement for the user.

PUT /agreements/{agreementId}/me/note

Updates the latest note associated with an agreement.

GET /libraryDocuments/{libraryDocumentId}/me/note

Retrieves the latest note on a library template for the user.

PUT /libraryDocuments/{libraryDocumentId}/me/note

Updates the latest note of a library document for the API user.

GET /widgets/{widgetId}/me/note

Retrieves the latest note of a widget for the API user.

PUT /widgets/{widgetId}/me/note

Updates the latest note of a widget for the API user.

Reminders

The reminder APIs in v6 enable clients to create reminders for any participant at any time before their action on the agreement. The capability to list all reminders on an agreement is also availaible in v6. These capabilities will significantly improve clients’ experience of handling reminders for agreements. The table below lists all the endpoints in this set:

Authoring API

Functionality

POST /agreements/{agreementId}/reminders

Sets reminders for a list of participants.

GET /agreements/{agreementId}/reminders

Retrieves all the reminders set on an agreement.

Resource views

There are a number of views associated with a resource. For example, an agreement may have an authoring view, agreement documents view, signing page view, or a manage page view with the agreement selected. The availaibility of all these views depends on both the state of the resource and also the relationship of the user with the resource. To access and customize these resource views, the v6 Adobe Sign API includes this endpoint to list all such views in their desired configuration:

Sample request/response:

Request - POST /agreements/{agreementId}/views

{
    "names": "DOCUMENT",
    "commonViewConfiguration": {
        "autoLoginUser": false,
        "noChrome": true,
        "locale": "en"
    }
}

Response - POST /agreements/{agreementId}/views

[
    {
        "name": "DOCUMENT",
        "url": "https://secure.echosign.com/account/agreements?aid=CBJCHBCAABAA0RVdUCYoR5kU9vh4-b4qHhYW_1r10hKw&pid=CBJCHBCAABAAH-F0jK3mHa53G7gr0SiftgdqE-jjwNVq&noChrome=true",
        "embeddedCode": "<script type='text/javascript' language='JavaScript' src='https://secure.echosign.com/embed/account/agreements?aid=CBJCHBCAABAA0RVdUCYoR5kU9vh4-b4qHhYW_1r10hKw&pid=CBJCHBCAABAAH-F0jK3mHa53G7gr0SiftgdqE-jjwNVq&noChrome=true'></script>"
    }
]

Resource visibility

The agreement visibility feature enables a client to control which resources are included in the response body of the enumeration/reource listing APIs like GET /agreements. This helps users to hide all resources from their view that they don’t want to focus on. The PUT /resource/{resourceId}/me/visibility API exposes this functionality, wherein a resource can be an agreement, widget, template or megasign in Adobe Sign.

Suppress email

The suppress email feature, in a broader sense, enables us to specify which emails participants receive while sending out the agreement. This feature is exposed through our agreement creation API, POST /agreements. Here is a sample request that allows only agreement initiation emails to be sent to the participants:

POST /agreements with email configuration

{
    "fileInfos": [{
        "transientDocumentId": "<a-valid-transient-resource-id>"
    }],

    "name": "Sample Agreement with email config",

    "participantSetsInfo": [{
        "memberInfos": [{
            "email": "signer@adobe.com"
        }],
        "role": "SIGNER",
        "order": "1"
    }],

    "emailOption": {
        "sendTarget": {
            "initEmails": "ALL",
            "inFlightEmails": "NONE",
            "completionEmails": "NONE"
        }
    },

    "signatureType": "ESIGN",
    "status": "IN_PROCESS"
}

Webhooks

Callbacks in Adobe Sign are now handled through webhooks. A webhook is essentially a web service designed to listen for and respond to POST requests. When you create a webhook and register it with Adobe Sign, Adobe Sign’s Webhook Subscription Service will notify your webhook of any relevant event by sending a POST request via HTTPS containing a JSON object with the details of the event. Your webhook then passes those details on to your application for handling. The service operates on a push model: your app doesn’t have to poll for events at all—those events are automatically sent to your webhook as they happen, with virtually no delay, so your app is instantaneously, automatically updated with any changes.

See Webhooks in Adobe Sign v6 to learn how webhooks work in Adobe Sign and how to set one up for your application.

API Change Log

Adobe Sign version 6 includes many changes to the API model.

On this page: New APIs Updated APIs Removed APIs

New APIs

Retrieves the latest note on an agreement for the user.
Returns all the users associated with an agreement: participant set, cc’s, shared participants, and sender.
Lists all the reminders on an agreement.
Retrieves the latest note on a library template for the user.
Retrieves the file stream of the original CSV file that was uploaded by the sender while creating the MegaSign.
Lists all the events of a MegaSign.
Lists all the groups to which the user identified by the userId belongs.
Creates form fields in an agreement using a library template.
Allows users to share agreements with other users.
Returns the requested views such as manage page view, agreement documents view, post send page view associated with an agreement in the requested configuration.
Returns the requested views, such as manage page view, library documents view, and send page view of this library document in the requested configuration.
Provides all the views associated with a megaSign, such as manage page view, documents view, etc.
Provides all the views associated with a user, like profile page view, account page view, or manage page view.
Returns the requested views, such as manage page view, widget documents view, and post send page view associated with a widget in the requested configuration.
Updates the data of an agreement, such as name, participants, etc.
Edit or modify an existing form field on an agreement document.
Manage the visibility of an agreement in GET /agreements.
Updates an existing participant set of an agreement. Adds some more capability to the existing recipient update feature:
  1. Allows replacing a specific participant in the set instead of choosing between either replacing all participants or no one.

  2. Allows sender to replace participants who are not the current signer as well.

Transitions an agreement from one state to another: for example, DRAFT to IN_PROCESS. Note that not all transitions are allowed. An allowed transition would follow the following sequence: DRAFT -> AUTHORING -> IN_PROCESS -> CANCELLED.

PUT /libraryDocuments/{libraryDocumentId} Updates the data of a library document, such as name, type, scope, etc.

A new API to control visibility of an agreement in the GET /libraryDocuments response.
Transitions a library document from one state to another: for example, AUTHORING to ACTIVE. Note that not all transitions are allowed. An allowed transition would follow the following sequence: AUTHORING -> ACTIVE.
Transitions a MegaSign from one state to another: for example, IN_PROCESS to CANCELLED. Note that not all transition are allowed. An allowed transition would follow the following sequence: IN_PROCESS -> CANCELLED.
Migrates the user to a different group or updates their role in the existing group.
Transitions a widget from one state to another: for example, DRAFT to IN_PROCESS. Note that not all transition are allowed. An allowed transition would follow one of the following sequences: DRAFT -> AUTHORING -> ACTIVE, ACTIVE <-> INACTIVE, DRAFT -> CANCELLED.

Updated APIs

GET /baseUris

  • The endpoint path is now changed to be consistent with the camel casing convention in Adobe Sign API (base_uri is now baseUri).

  • The response parameter is also renamed to have camel casing.

GET /agreements

  • The response is paginated.

  • The response also lists all the user-created drafts.

  • Filter to show/hide hidden agreements.

  • Data returned is same as v5.

GET /agreements/{agreementId}

  • The model is consistent with the corresponding POST and PUT APIs.

  • Participants and events information are retrieved through separate granular APIs.

  • Detailed participants and events information are available through separate endpoints.

Includes audit reports for draft creation.
Uses participantId instead of participantEmail as a filter.

GET /agreements/{agreementId}/documents

  • Uses participantId instead of participantEmail as a filter.

  • There are minor changes in the field names.

GET /agreements/{agreementId}/documents/imageUrls

  • Uses participantId instead of participantEmail as a filter.

  • There are minor changes in the field names.

  • Provides annotated image URLs with documentId and page number.

GET /agreements/{agreementId}/documents/{documentId}/imageUrls

  • Uses participantId instead of participantEmail as a filter.

  • There are minor changes in the field names.

GET /libraryDocuments

  • Response is paginated.

  • Creator email and status is in the response.

  • We’ve added a query parameter to view/un-view all the hidden agreements.

  • The scope parameter in v5 is mapped to sharingMode in v6.

  • PERSONAL in v5 is now USER in v6.

  • SHARED in v5 is now `GROUP in v6.

  • The libraryTemplateType filter is dropped from this API. This will be available along with other filtering through search services.

GET /libraryDocuments/{libraryDocumentId}

  • Events have been removed from the response of this endpoint and are now returned through a dedicated events endpoint.

  • The latestVersionId parameter is now removed from here and will be available in GET /libraryDocuments.

  • We have removed obsolete and unnecessary parameters: locale, participants, message and securityOptions.

  • The model is consistent with the corresponding POST and PUT operations.

GET /libraryDocuments/{libraryDocumentId}/documents

  • Added a label parameter for using in the custom workflow.

  • A versionId of the documents has been added as a filter.

A base64 encoding option is available for the generated PDF.

GET /users

  • Paginated response.

  • The groupId is no longer returned through this API.

  • Returns the new account admin information.

GET /users/{userId}

  • A few unusable fields were dropped.

  • We have removed capability flags from here.

Paginated response.
The model is consistent with the POST and PUT operations.

POST /agreements

  • The request body is now consistent with its GET/PUT counterpart. A common agreement model is used across all these APIs.

  • Interactive options have been removed from the request body and is available through the separate POST /agreements/{agreementId}/views API.

  • Support for form fields, form fields layer template, amd merge fields has been removed from here and will now be available through the authoring APIs.

  • The document visibility feature is available in v6.

  • This API is more responsive as it is now asynchronous.

  • Clients can build up an agreement sequentially using draft functionality.

  • The signatureFlow parameter is dropped from v6 and is now implicitly inferred through the sequence that the values of other parameters are given in all participant sets.

  • The Suppress Email feature is available in v6.

  • You can create an agreement in different states using the transistionState field.

  • There is a separate state transitioning (from draft to agreement) API.

POST /agreements/{agreementId}/members/participantSets/{participantSetId}/delegatedParticipantSets

POST /agreements/{agreementId}/reminders

Was: POST /reminders

  • Creates reminders for multiple participants.

  • Lets you set the next send date, note, frequency, and other parameters.

  • You can track each reminder through the ID returned from here.

POST /libraryDocuments

  • The model is consistent with the corresponding GET & PUT operations.

  • Obsolete parameters libraryDocumentId and libraryDocumentName have been removed from fileInfosstructure. This was present in prior versions, but was unusable, because we did not allow library template creation using an existing template through the API.

  • Interactive options have been removed from the request body; the equivalent functionality is now available through the POST /libraryDocuments/{libraryDocumentId}/views API.

  • You can create a library template in different states using the transition state field.

  • There is a separate state transitioning (Authoring to Active) API.

POST /transientDocuments

  • Returns an UNSUPPORTED_MEDIA_TYPE error for unsupported media types in Adobe Sign.

POST /widgets

  • The request body is now consistent with this API’s GET/PUT counterpart. A common agreement model is used across all these APIs.

  • Form fields layer template and Merge Fields support have been removed in v6 for widget creation.

  • The signatureFlow parameter has been dropped and the workflow is inferred through the order in the additionalParticipantSetsInfo parameter.

PUT /agreements/{agreementId}/state

Was: PUT /agreements/{agreementId}/status

  • Dropped the PUT /agreements/{agreementId}/status API, as it was offering a dedicated endpoint for modifying a property of the agreement resource.

  • The new API offers an action-based semantic to transition between states of an agreement.

  • The intended final state of the agreement is provided in the request body and the response indicates if the agreement was successfully transitioned into the intended state.

  • This API can be used by the sender to cancel the agreement.

Updating the group of the user is now handled via the PUT /users/{userId}/groups API.
This is functionally the same as before, but the API structure is revamped to make it consistent with other state transition APIs in v6.

Removed APIs

The equivalent functionality of removing an agreement permanently from a user’s manage page can be achieved through the combination of DELETE /agreements/{agreementId}/documents and PUT /visibility.
The v5 API had the redundant functionality of providing combined agreement docs, which can be achieved through the GET /document API.