Webhook APIs¶
Webhook APIs are the means by which your integration communicates with the Acrobat Sign service about webhooks. Use the various API endpoints to create, delete, modify, and retrieve status information about your webhooks.
Acrobat 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 |
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.
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 Acrobat 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.
Note
Acrobat Sign now includes a new Object webhookEndpointInfo
to associate a webhook to a webhookEndpoint. When using the webhookEndpointInfo, do not provide a webhookUrlInfo.
webhookInfo {
...
webhookEndpointInfo : {
webhookEndpointId: "",
domainPrefix: "",
urlSuffix: ""
}
}
Attribute |
Description |
---|---|
webhookEndpointId |
The webhookEndpointId that to be associated with this webhook. |
domainPrefix |
Optional URL subdomain value. This value will be used to replace the first wildcard (*). |
urlSuffix |
Optional Url Suffix to append to the WebhookEndpointId. This value will be used to replace the wildcard (*) at the end. |
webhookEndpointInfo Error codes
You should be prepared to handle new errors that may be returned from APIs or changes in existing error codes. It is important to note that error codes can evolve over time. You must be prepared to implement default error handling for unclear error events.
Code |
Error code |
Message |
---|---|---|
400 |
INVALID_JSON |
An invalid JSON was specified. |
404 |
INVALID_WEBHOOK_ENDPOINT_ID |
WebhookEndpointId is not found. Request id: <hash> |
GET /webhooks¶
Entity |
Value |
---|---|
Description |
Get a list of webhooks created by the access token user |
OAuth scopes |
webhook_read |
Query parameters |
|
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": "webhook linked to a webhookEndpoint",
"lastModified": "2018-02-06T22:52:27-08:00",
"scope": "RESOURCE",
"resourceType": "AGREEMENT",
"resourceId": "3dffwifvgvfguierfreokfperfprfppr",
"webhookSubscriptionEvents": [
"AGREEMENT_RECALLED"
],
"status": "ACTIVE",
"webhookEndpointInfo": {
"webhookEndpointId": "",
"domainPrefix": "",
"urlSuffix": ""
}
}
],
"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.
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.
Code |
Error code |
Message |
---|---|---|
304 |
RESOURCE_NOT_MODIFIED |
The resource is not modified. |
404 |
INVALID_WEBHOOK_ID |
The webhookId specified is invalid |
Note
You can update a webhook that is linked to webhookEndpoint by providing the webhookEndpointInfo in the Request body.
"userWebhookList": [
{
...
"webhookEndpointInfo": {
"webhookEndpointId": "",
"domainPrefix": "",
"urlSuffix": ""
}
},
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.
Code |
Error code |
Message |
---|---|---|
400 |
|
Required parameters are missing. |
400 |
|
There is already a webhook registered with same configuration. |
400 |
|
An invalid JSON was specified. |
400 |
|
The webhook conditional parameters specified are invalid. |
400 |
|
One or more webhook subscription events specified are invalid. |
400 |
|
The If-Match header missing. |
400 |
|
The webhook you are trying to update cannot be modified. |
400 |
|
This webhook can’t be activated. The resource has reached the maximum number of active webhooks. |
404 |
|
The |
412 |
|
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.
Note
You can update a webhook that is linked to webhookEndpoint by providing the webhookEndpointInfo in the Request body.
webhookInfo {
...
webhookEndpointInfo : {
webhookEndpointId: "",
domainPrefix: "",
urlSuffix: ""
}
}
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: |
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.
HTTPS status code |
Error code |
Message |
---|---|---|
400 |
|
Required parameters are missing. |
400 |
|
There is already a webhook registered with same configuration. |
400 |
|
An invalid JSON was specified. |
400 |
|
The If-Match header is missing. |
400 |
|
The webhook you are trying to update cannot be modified. |
400 |
|
This webhook can’t be activated. The resource has reached the maximum number of active webhooks. |
404 |
|
The |
412 |
|
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.
Code |
Error code |
Message |
---|---|---|
403 |
FORBIDDEN |
Delete is not allowed. |
404 |
INVALID_WEBHOOK_ID |
The webhookId is invalid. |
Standard API request error codes¶
Any API request may return any of these standard error codes:
HTTPS status code |
Error code |
Message |
---|---|---|
400 |
|
The request provided is invalid. |
400 |
|
An invalid JSON was specified. |
400 |
|
The value provided in the |
400 |
|
The value provided in |
400 |
|
Some miscellaneous error has occurred. |
401 |
|
You cannot work on behalf of this user. |
401 |
|
The user has registered but has not verified their email address. The user must use the Acrobat Sign web site to complete verification. |
401 |
|
The authorization header was not provided. |
401 |
|
The access token provided is invalid or has expired. |
401 |
|
An invalid user ID or email was provided in the |
401 |
|
An invalid user ID or email was provided in the |
403 |
|
Your account is locked because an administrator has not agreed to Acrobat Sign’s Terms of Use. Please contact your administrator to activate your account. |
404 |
|
The API caller does not have the permission to execute this operation. |
500 |
|
Some miscellaneous server error has occurred. |
Standard API request headers¶
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 |
---|---|
|
An access token with the correct scopes. |
|
The userId or email of the API caller using the account or group token in the format |
|
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 Acrobat Sign. AWS Lambda Functions support Node.js (JavaScript), Java, Python, C#, and Go.
Create an AWS Lambda function¶
To create an AWS Lambda function:
Login to your AWS Management Console and select the AWS Lambda service from the services list.
Choose to create a Lambda function, then select Author from Scratch.
In the Configure function page, enter the function name “lambdaWebhooks” and select Node.js 4.3 as the runtime.
For the role, choose an existing role or Create a new role from template(s).
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.
Select Create function.
On the new AWS lambda function page, select Edit code inline as the code entry type; keep index.handler as the Handler.
Register your Acrobat Sign webhook¶
Before registering a webhook, Acrobat Sign verifies that the webhook URL that is provided in the registration request really intends to receive notifications; see verifyintent. For this purpose, when a new webhook registration request is received by Acrobat 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.
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.
In the Create new API page, select New API and enter webhooks as the API name.
Select Create API.
From the Actions drop-down list, select Create Resource.
Check the “Configure as proxy resource” option and enter “validate” as the Resource Name and “{proxy+}” in the Resource Path.
Leave the “Enable API Gateway CORS” option unchecked and select Create Resource.
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).
Enter “validate” as the Lambda Function and select Save.
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:
Deploy the API¶
The next step is deploying this API so it becomes ready to use:
In the Actions drop-down, select Deploy API. The Deploy API dialog appears.
Select [New Stage] for the Deployment stage and enter “prod” (or anything you like to identify this stage) for the Stage name.
Select Deploy.
The new API is now ready to use. You can find the invoke URL in the blue box as shown below:
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 Acrobat 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 Acrobat 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:
A Microsoft account with license to create Azure Functions applications.
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.
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.
Creating an Azure Functions Trigger-Webhook¶
Create a JS HttpTrigger function¶
Login with your Microsoft account at https://portal.azure.com/
Select Function Apps from your account dashboard menu. This will open your list of Azure Function apps.
Choose the app wherein you want to create this new function.
Select the + icon to create a new Azure function.
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.
Register the webhook¶
Before registering a webhook successfully, Acrobat Sign verifies that the webhook URL that is provided in the registration request really intends to receive notifications; see verifyintent. For this purpose, when a new webhook registration request is received by Acrobat 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.
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();
};
Test the behavior by mocking the request:
Select the Test button at the extreme right corner.
Mock 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.
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();
};
Test the behavior by mocking the request:
Select the Test button at the extreme right corner.
Mock the dummy request:
Note: The same behavior for clientId
is expected when the Webhook URL receives POST notifications.
Once you have verified the behavior, the webhook URL is functional as per Acrobat Sign standards. You can further update your new webhook and add custom logic as needed for your application.
Get the function’s URL¶
- Select Get function URL:
- Copy the URL and use it for creating webhooks in Acrobat Sign.