Webhook APIs

Webhook APIs are the means by which your integration communicates with the Adobe Sign service about webhooks. Use the various API endpoints to create, delete, modify, and retrieve status information about your webhooks.

Adobe Sign APIs include the endpoints described below.

POST /webhooks

Entity

Value

Description

Creates a webhook

Endpoint operation

/webhooks

OAuth scopes

webhook_write

Request object

WebhookInfo:

{
    "name": "",
    "scope": "",
    "state": "",
    "webhookSubscriptionEvents": [
      ""
    ],
    "webhookUrlInfo": {
      "url": ""
    },
    "applicationDisplayName": "",
    "applicationName": "",
    "created": "",
    "id": "",
    "lastModified": "",
    "resourceId": "",
    "resourceType": "",
    "status": "",
    "webhookConditionalParams": {
      "webhookAgreementEvents": {
          "includeDetailedInfo": false,
          "includeDocumentsInfo": false,
          "includeParticipantsInfo": false,
          "includeSignedDocuments": false
      },
      "webhookMegaSignEvents": {
          "includeDetailedInfo": false
      },
      "webhookWidgetEvents": {
          "includeDetailedInfo": false,
          "includeDocumentsInfo": false,
          "includeParticipantsInfo": false
      }
    }
  }

Response header

Location Header specifying the resource location of the webhook

Response content type

application/json

Response object

WebhookCreationResponse { "id" : "" }

HTTPS status code

201

Error codes

Please note that new errors could be returned from APIs or existing error codes can be evolved. Clients are expected to be prepared to do default handling for error scenarios which they do not understand.

Error codes

Code

Error code

Message

400

INVALID_ARGUMENTS

One or more arguments to the method are invalid.

400

INVALID_WEBHOOK_URL

The Webhook URL specified is invalid.

400

INVALID_RESOURCE_ID

Resouce Id specified is invalid.

400

INVALID_RESOURCE_TYPE

The resource type is invalid.

400

INVALID_WEBHOOK_CONDITIONAL_PARAMS

The conditional parameters specified are invalid.

400

MISSING_REQUIRED_PARAM

The required parameters are missing.

400

WEBHOOK_LIMIT_EXCEEDED

This webhook can’t be created. The events array {events} has reached the maximum number of active webhooks.

400

DUPLICATE_WEBHOOK_CONFIGURATION

There is already a webhook registered with same configuration.

400

INVALID_WEBHOOK_STATE

The webhook state specified is invalid.

400

INVALID_WEBHOOK_SUBSCRIPTION_EVENTS

One or more webhook subscription events specified are invalid.

403

WEBHOOK_CREATION_NOT_ALLOWED

Webhook creation is not allowed.

This API will be used to create a webhook on a particular resource in Adobe Sign.

  • You need to register the webhook with your application and a user token using this API.

  • Group level webhooks can only be created by a Group admin and Account level webhooks can only be created by an Account admin.

  • The user can customize the events for which the webhook is triggered in this call.

The HTTP Location header field is returned in the response to provide information about the location of a newly created resource. Multiple webhooks can be created on a single resource. Also, multiple webhooks can share the same URL.

GET /webhooks

Entity

Value

Description

Get a list of webhooks created by the access token user

OAuth scopes

webhook_read

Query parameters

  • showInactiveWebhooks: boolean: A query parameter to fetch all the inactive webhooks along with the active webhooks.

  • scope: Scope of the webhook. The possible values are ACCOUNT, GROUP, USER, or RESOURCE.

  • resourceType: The type of resource on which webhook was created. The possible values are AGREEMENT, WIDGET, and MEGASIGN.

Response content type

application/json

Response object

WebhooksInfo

{
    "userWebhookList": [
      {
          "applicationName": "Application for REST Swagger Documentation",
          "applicationId": "pUQL757H2R2",
          "id": "CBJCHBCAABAAtW5qb_gRDgssqn6tvLvCcav0VqYi0WTR",
          "name": "user level webhook",
          "lastModified": "2018-02-06T22:52:27-08:00",
          "scope": "USER",
          "webhookSubscriptionEvents": [
            "AGREEMENT_RECALLED"
          ],
          "webhookUrlInfo": {
            "url": "https://testUrl"
          },
          "status": "ACTIVE"
      },
      {
          "applicationName": "Application for REST Swagger Documentation",
          "applicationDisplayName ": "REST Swagger",
          "id": "CBJCHBCAABAAtW5qb_gRDgssqn6tvLvCcav0VqYi0WTR",
          "name": "",
          "lastModified": "2018-02-06T22:52:27-08:00",
          "scope": "RESOURCE",
          "resourceType": "AGREEMENT",
          "resourceId": "3dffwifvgvfguierfreokfperfprfppr",
          "webhookSubscriptionEvents": [
            "AGREEMENT_RECALLED"
          ],
          "webhookUrlInfo": {
            "url": "https://testResource"
          },
          "status": "ACTIVE"
      }
    ],
    "page": {
      "nextCursor": " "
    }
}

HTTPS status code

200

Error codes

Please note that new errors could be returned from APIs or existing error codes can be evolved. Clients are expected to be prepared to do default handling for error scenarios which they do not understand.

Error codes

HTTPS status code

Error code

Message

400

INVALID_ARGUMENTS

One or more arguments to the method are invalid.

400

INVALID_CURSOR

The page cursor provided is invalid.

400

INVALID_PAGE_SIZE

Page size is either invalid or not within the permissible range.

GET /webhooks/{webhookId}

Entity

Value

Description

List details of a webhook.

Endpoint operation

/webhhooks/{webhookId}

OAuth scopes

webhook_read

Response content type

application/json

Response object

WebhookInfo

  {
  "scope": "",
  "webhookSubscriptionEvents": [
      ""
  ],
  "webhookUrlInfo": {
      "url": ""
  },
  "name": "",
  "status": "",
  "applicationDisplayName ": "",
  "applicationName": "",
  "created": "date",
  "id": "",
  "lastModified": "date",
  "resourceId": "",
  "resourceType": "",
  "webhookConditionalParams": {
      "webhookAgreementEvents": {
          "includeDetailedInfo": false,
          "includeDocumentsInfo": false,
          "includeParticipantsInfo": false,
          "includeSignedDocuments": false
      },
      "webhookMegaSignEvents": {
          "includeDetailedInfo": false
      },
      "webhookWidgetEvents": {
          "includeDetailedInfo": false,
          "includeDocumentsInfo": false,
          "includeParticipantsInfo": false
      }
  }
}

HTTPS status code

200

Error codes

Please note that new errors could be returned from APIs or existing error codes can be evolved. Clients are expected to be prepared to do default handling for error scenarios which they do not understand.

Error codes

Code

Error code

Message

304

RESOURCE_NOT_MODIFIED

The resource is not modified.

404

INVALID_WEBHOOK_ID

The webhookId specified is invalid

PUT /webhooks/{webhookId}

Entity

Value

Description

This endpoint is used to update the webhook resource.

Endpoint operation

/webhooks/{webhookId}

OAuth scopes

webhook_write

Request header

Standard header. Additionally, If-Match headers, which will be processed as per the Concurrency section of the DC API Guideline.

Request body

WebhookInfo

{
  "name": "",
  "scope": "",
  "state": "",
  "webhookSubscriptionEvents": [
    ""
  ],
  "webhookUrlInfo": {
    "url": ""
  },
  "applicationDisplayName": "",
  "applicationName": "",
  "created": "",
  "id": "",
  "lastModified": "",
  "resourceId": "",
  "resourceType": "",
  "status": "",
  "webhookConditionalParams": {
    "webhookAgreementEvents": {
        "includeDetailedInfo": false,
        "includeDocumentsInfo": false,
        "includeParticipantsInfo": false,
        "includeSignedDocuments": false
    },
    "webhookMegaSignEvents": {
        "includeDetailedInfo": false
    },
    "webhookWidgetEvents": {
        "includeDetailedInfo": false,
        "includeDocumentsInfo": false,
        "includeParticipantsInfo": false
    }
  }
}

Response content type

application/json

Response object

Empty response

HTTPS status code

204

Error codes

Please note that new errors could be returned from APIs or existing error codes can be evolved. Clients are expected to be prepared to do default handling for error scenarios which they do not understand.

Error codes

Code

Error code

Message

400

MISSING_REQUIRED_PARAM

Required parameters are missing.

400

DUPLICATE_WEBHOOK_CONFIGURATION

There is already a webhook registered with same configuration.

400

INVALID_JSON

An invalid JSON was specified.

400

INVALID_WEBHOOK_CONDITIONAL_PARAMS

The webhook conditional parameters specified are invalid.

400

INVALID_WEBHOOK_SUBSCRIPTION_EVENTS

One or more webhook subscription events specified are invalid.

400

MISSING_IF_MATCH_HEADER

The If-Match header missing.

400

UPDATE_NOT_ALLOWED

The webhook you are trying to update cannot be modified.

400

WEBHOOK_LIMIT_EXCEEDED

This webhook can’t be activated. The resource has reached the maximum number of active webhooks.

404

INVALID_WEBHOOK_ID

The webhookId is invalid.

412

RESOURCE_MODIFIED

The resource is already modified with a newer version.

Only events and conditional parameters can be modified. The webhook URL can’t be modified once the webhook is created. The modification can also be done in the INACTIVE state.

PUT /webhooks/{webhookId}/state

Entity

Value

Description

This endpoint will update the state of a webhook identified by webhookId in the path.

Endpoint operation

/webhooks/{webhookId}/state

OAuth scopes

webhook_write

Request header

Standard header. Additionally, If-Match headers, which will be processed as per the Concurrency section of the DC API Guidelines.

Request body

WebhookInfo: {"state": ""}

Response content type

application/json

Response object

Empty response

HTTPS status code

204

Error codes

Please note that new errors could be returned from APIs or existing error codes can be evolved. Clients are expected to be prepared to do default handling for error scenarios which they do not understand.

Error codes

HTTPS status code

Error code

Message

400

MISSING_REQUIRED_PARAM

Required parameters are missing.

400

DUPLICATE_WEBHOOK_CONFIGURATION

There is already a webhook registered with same configuration.

400

INVALID_JSON

An invalid JSON was specified.

400

MISSING_IF_MATCH_HEADER

The If-Match header is missing.

400

UPDATE_NOT_ALLOWED

The webhook you are trying to update cannot be modified.

400

WEBHOOK_LIMIT_EXCEEDED

This webhook can’t be activated. The resource has reached the maximum number of active webhooks.

404

INVALID_WEBHOOK_ID

The webhookId is invalid.

412

RESOURCE_MODIFIED

The resource is already modified with a newer version.

DELETE /webhooks/{webhookId}

Entity

Value

Description

This endpoint is used to delete the webhook resource. This is the terminal state of the webhook and the action is irreversible.

Endpoint operation

/webhooks/{webhookId}

OAuth scopes

webhook_delete

Request header

Standard header

HTTPS status code

204

Error codes

Please note that new errors could be returned from APIs or existing error codes can be evolved. Clients are expected to be prepared to do default handling for error scenarios which they do not understand.

Error codes

Code

Error code

Message

403

FORBIDDEN

Delete is not allowed.

404

INVALID_WEBHOOK_ID

The webhookId is invalid.

Standard error codes in every API request

Any API request may return any of these standard error codes:

HTTPS status code

Error code

Message

400

BAD_REQUEST

The request provided is invalid.

400

INVALID_JSON

An invalid JSON was specified.

400

INVALID_ON_BEHALF_OF_USER_HEADER

The value provided in the x-on-behalf-of-user header is in invalid format.

400

INVALID_X_API_USER_HEADER

The value provided in x-api-user header is in invalid format.

400

MISC_ERROR

Some miscellaneous error has occurred.

401

UNAUTHORIZED

You cannot work on behalf of this user.

401

UNVERIFIED_USER

The user has registered but has not verified their email address. The user must use the Adobe Sign web site to complete verification.

401

NO_AUTHORIZATION_HEADER

The authorization header was not provided.

401

INVALID_ACCESS_TOKEN

The access token provided is invalid or has expired.

401

INVALID_USER

An invalid user ID or email was provided in the x-user header.

401

INVALID_ON_BEHALF_OF_USER

An invalid user ID or email was provided in the x-on-behalf-of-user header.

403

API_TERMS_NOT_ACCEPTED

Your account is locked because an administrator has not agreed to Adobe Sign’s Terms of Use. Please contact your account administrator to activate your account.

404

PERMISSION_DENIED

The API caller does not have the permission to execute this operation.

500

MISC_SERVER_ERROR

Some miscellaneous server error has occurred.

Standard headers in every API request

Every API request will have the following standard headers. If Any API in the list above does not have one or more of the following headers, the API will explicitly document this fact.

Header Name

Description

AUTHORIZATION

An access token with the correct scopes.

x-api-user

The userId or email of the API caller using the account or group token in the format userid:{userId} OR email:{email}. If it is not specified, then the caller is inferred from the token.

x-on-behalf-of-user

Account sharing: The user on whose behalf the API caller is working.

Using AWS Lambda Functions

AWS Lambda Functions is a serverless computing service offered by Amazon Web Services. AWS Lambda Functions offer you a platform in which you can execute function code on demand over the internet without the need to manage your own web servers. This gives you a no-overhead solution for hosting functions in the cloud, such as webhooks for Adobe Sign. AWS Lambda Functions support Node.js (JavaScript), Java, Python, C#, and Go.

Create an AWS Lambda function

To create an AWS Lambda function:

  1. Login to your AWS Management Console and select the AWS Lambda service from the services list.

_images/sign_webhooks_aws_1.png
  1. Choose to create a Lambda function, then select Author from Scratch.

_images/sign_webhooks_aws_2.png
  1. In the Configure function page, enter the function name “lambdaWebhooks” and select Node.js 4.3 as the runtime.

  2. For the role, choose an existing role or Create a new role from template(s).

  3. If you have chosen Create new role from template(s), enter a role name (for instance, “role-lambda”) and select Simple Microservice permissions from the policy templates list.

  4. Select Create function.

  5. On the new AWS lambda function page, select Edit code inline as the code entry type; keep index.handler as the Handler.

Register your Adobe Sign webhook

Before registering a webhook, Adobe Sign verifies that the webhook URL that is provided in the registration request really intends to receive notifications; see Verification of intent of the webhook URL. For this purpose, when a new webhook registration request is received by Adobe Sign, it first makes an HTTPS GET verification request to the webhook URL with a custom HTTP header, X-AdobeSign-ClientId. The value in this header is set to the client ID of the application that is requesting to create and register the webhook. The webhook URL must respond to this verification request with a 2XX response code, and it must send back the same client ID value in one of the following two ways: Also note the same behaviour for clientID is expected when the Webhook URL receives POST notifications.

Case 1: Pass the client ID as X-AdobeSign-ClientId in the response header

This is the same header which was passed in the request, and it must be echoed back in the response.

Replace the contents of the Index.js file with the following code snippet:

exports.handler = function index(event, context, callback) {
  // Fetch client id
  var clientid = event.headers['X-AdobeSign-ClientId'];

  //Validate it
  if (clientid =="BGBQIIE7H253K6") //Replace 'BGBQIIE7H253K6' with the client id of the application using which the webhook is created
  {
    var response = {
        statusCode: 200,
        headers: {
            "X-AdobeSign-ClientId": clientid
        }
     };
   callback(null,response);
  }
  else {
   callback("Oops!! illegitimate call");
  }
}

Case 2: Pass the client ID in the response body with the key xAdobeSignClientId

In the JSON response body, pass the key xAdobeSignClientId with its value being the same client ID that was sent in the request header.

Replace the contents of the Index.js file with the following code snippet:

exports.handler = function index(event, context, callback) {
 // Fetch client id
 var clientid = event.headers['X-AdobeSign-ClientId'];

 //Validate it
 if (clientid =="BGBQIIE7H253K6") //Replace 'BGBQIIE7H253K6' with the client id of the application using which the webhook is created
 {
   var responseBody = {
        xAdobeSignClientId : clientid
   };

    var response = {
        statusCode: 200,
        body: JSON.stringify(responseBody)

    };
   callback(null,response);
 }
 else {
   callback("Opps!! illegitimate call");
  }
}

Save the function. The Lambda function is created, and you are almost ready to use it in a real-time webhook.

Configure the AWS API Gateway

To make this Lambda function publicly accessible through a HTTP method, you need to configure the AWS API Gateway using your function as the backend for the API.

  1. In the AWS Management Console, select API Gateway from the AWS Services list.

    Note: If this is your first time in the API Gateway console, you’ll see a Getting Started screen. Select Get Started to proceed. Clear the dialog for the example API. If you’ve used the API Gateway service before, simply select Create API to proceed.

  2. In the Create new API page, select New API and enter webhooks as the API name.

_images/sign_webhooks_aws_3.png
  1. Select Create API.

  2. From the Actions drop-down list, select Create Resource.

  3. Check the “Configure as proxy resource” option and enter “validate” as the Resource Name and “{proxy+}” in the Resource Path.

  4. Leave the “Enable API Gateway CORS” option unchecked and select Create Resource.

  5. Keep the Lambda Function Proxy selected as the Integration type and select the region where you have created your Lambda function in the Lambda region drop-down list (probably it’s the same region where you are creating the API Gateway).

  6. Enter “validate” as the Lambda Function and select Save.

  7. An Add Permission to Lambda Function pop-up window appears; select OK.

If all the above steps are executed successfully, you’ll see something like this:

_images/sign_webhooks_aws_4.png

Deploy the API

The next step is deploying this API so it becomes ready to use:

  1. In the Actions drop-down, select Deploy API. The Deploy API dialog appears.

  2. Select [New Stage] for the Deployment stage and enter “prod” (or anything you like to identify this stage) for the Stage name.

  3. Select Deploy.

The new API is now ready to use. You can find the invoke URL in the blue box as shown below:

_images/sign_webhooks_aws_5.png

Take note of this URL as you’ll need to enter it as your real-time webhook URL.

Ready to Use

It’s done. Use the above URL with “/{nodeJSfunctionName}” appended as the webhook URL in your POST /webhooks API request. Once you have verified the behavior, the webhook URL is functional as per Adobe Sign standards. You can further update your new webhook and add custom logic as needed for your application.

Using Azure Functions

Azure Functions is Microsoft’s serverless computing cloud platform. Using Azure Functions, you can write functional code and host it in the Azure cloud, ready to execute on demand. This always-on functionality, combined with the ease of management offered by cloud-based serverless architecture, makes Azure Functions a viable alternative for hosting your Adobe Sign webhooks.

Azure Functions executes individual serverless functions within a function app. Function apps can host many different functions, and you can have many function apps on Azure; so the infrastructure enables you to organize related functions into apps.

Prerequisites

To create and host a webhook in Azure Functions, you need:

  1. A Microsoft account with license to create Azure Functions applications.

  2. An Azure Functions app. If you don’t have an existing app, you can create it for the purpose: see Create your first function in the Azure portal in the Azure documentation.

  3. For this example, basic knowledge of JavaScript. Azure Functions understands and executes functions written in several different languages; see Supported languages in Azure Functions in the Azure documentation.

Steps to create an Azure Functions Trigger that serves as an Adobe Sign Webhook

Create a JavaScript HttpTrigger function

  1. Login with your Microsoft account at https://portal.azure.com/

  2. Select Function Apps from your account dashboard menu. This will open your list of Azure Function apps.

_images/sign_webhooks_azure_1.png
  1. Choose the app wherein you want to create this new function.

  2. Select the + icon to create a new Azure function.

_images/sign_webhooks_azure_2.png
  1. Select “Webhook + API” as the scenario and “JavaScript” as the language; then select “Create this function”.

This will create a new function that has the capability of handling incoming API requests.

Add logic to register your Adobe Sign webhook

Before registering a webhook successfully, Adobe Sign verifies that the webhook URL that is provided in the registration request really intends to receive notifications; see Verification of intent of the webhook URL. For this purpose, when a new webhook registration request is received by Adobe Sign, it first makes an HTTPS GET verification request to the webhook URL with a custom HTTP header, X-AdobeSign-ClientId. The value in this header is set to the client ID of the application that is requesting to create and register the webhook. The webhook URL must respond to this verification request with a 2XX response code, and it must send back the same client ID value in one of the following two ways:

Case 1: Pass the client ID as ``X-AdobeSign-ClientId`` in the response header

This is the same header which was passed in the request, and it must be echoed back in the response.

  1. Replace the contents of the index.js file with the following code snippet:

module.exports = function (context, req) {
    var clientId = req.headers['x-adobesign-clientid'];
    // Validate that the incoming ClientID is genuine
    if (clientId === '123XXX456') {
        context.res = {
            // status: 200, /* Defaults to 200 */ // any 2XX response is acceptable
            body: "Notification Accepted",
            headers : {
                'x-adobesign-clientid' : req.headers['x-adobesign-clientid']
            }
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Opps!! Illegitimate Call identified"
        };
    }
    context.done();
};
  1. Test the behavior by mocking the request:

    • Select the Test button at the extreme right corner.

    • Mock the dummy request: The dummy request

    Although the response headers are not shown above, you can observe them by mocking the request with developer tools such as Postman.

Case 2: Pass the client ID in the response body with the key ``xAdobeSignClientId``

In the JSON response body, pass the key xAdobeSignClientId with its value being the same client ID that was sent in the request header.

  1. Replace the index.js file with the following:

module.exports = function (context, req) {
    var clientId = req.headers['x-adobesign-clientid'];
    // Validate that the incoming ClientID is genuine
    if (clientId === '123XXX456') {
        context.res = {
            // status: 200, /* Defaults to 200 */ // any 2XX response is acceptable
            body: {
                'xAdobeSignClientId' : clientId
            },
            headers : {
                'Content-Type' : 'application/json'
            }
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Opps!! Illegitimate Call identified"
        };
    }
    context.done();
};
  1. Test the behavior by mocking the request:

    • Select the Test button at the extreme right corner.

    • Mock the dummy request: image1

Note: The same behavior for clientId is expected when the Webhook URL receives POST notifications.

Ready to use

It’s done. Once you have verified the behavior, the webhook URL is functional as per Adobe Sign standards. You can further update your new webhook and add custom logic as needed for your application.

Get the function’s URL

  1. Select Get function URL:
    Get Function URL button
  2. Copy the URL and use it for creating webhooks in Adobe Sign.
    The function URL displayed for copying