Adobe Workfront Document Webhooks defines a set of API endpoints through which Workfront makes authorized API calls to an External Document Provider. This allows anyone to create a middleware plugin for any document storage provider.
The user experience for webhook-based integrations will be similar to that of existing document integrations, such as Google Drive, Box, and Dropbox. For example, a Workfront user will be able to perform the following actions:
To help jumpstart the development of a new webhooks implementation, Workfront provides a reference implementation. Code for this can be found at https://github.com/Workfront/webhooks-app. This implementation is Java-based and allows Workfront to connect documents on a network file system.
Workfront administrators can add a custom webhook integration for their company by navigating to Setup > Documents > Custom Integrations within Workfront. From the Custom Integration page within Setup, administrators can view a list of existing document Webhook integrations. From this page, integrations can be added, edited, enabled, and disabled. To add an integration, click the “Add Integration” button.
When adding an integration, the administrator will enter values for the following fields:
Field Name | Description |
---|---|
Name | The name of this integration. |
Base API URL | The location of the callback API. When making calls to the external system,Workfront will simply append the endpoint name to this address. For example, if the admin entered the Base API URL, " https://www.mycompany.com/api/v1 ", Workfront would using the following URL to get a document's metadata: https://www.mycompany.com/api/v1/metadata?id=1234. |
Request parameters | Optional values to be appended to the querystring of every API call. For example, access_type=offline.
|
Authentication Type | OAuth2 or ApiKey |
Authentication URL | (OAuth2 Only) The full URL used for user authentication. Workfront will navigate users to this address as part of the OAuth provisioning process. Note: Workfront will append a "state" parameter to the query string. The provider must pass this back to Workfront by appending it to the Workfront Redirect URI. |
Token Endpoint URL | (OAuth2 Only) The full API URL used to retrieve OAuth2 tokens. This is hosted by the webhook provider or external document provider
|
Client ID | (OAuth2 Only) The OAuth2 Client ID for this integration |
Client Secret | (OAuth2 Only) The OAuth2 Client Secret for this integration |
Workfront Redirect URI | (OAuth2 Only) This is a read-only field and is generated by Workfront. This value is used to register this integration with the external document provider. Note: As described above for Authentication URL, the provider must append the "state" parameter and its value to the querystring when performing the redirect. |
ApiKey | (ApiKey Only) Used to make authorized API calls to the webhook provider. The API key issued by the webhook provider. |
Workfront document webhooks supports two different forms of authentication: OAuth2 and ApiKey. In both cases, Workfront passes authentication tokens in the header when making an API call.
OAuth2 allows Workfront to make authorized API calls to a webhook provider on behalf of a user. Before doing so, the user must connect their external document provider account to Workfront and grant Workfront
access to act on their behalf. This handshaking process only happens once for each user. Here’s how it works:
The user begins connecting the webhook integration to their account. Currently, this is done by clicking the “Add Document” dropdown > “Add Service” > Custom integration name.
Workfront navigates the user the Authentication URL, which may prompt the user to login to the external document provider. This page is hosted by the webhook provider or the external document management system. When doing so Workfront adds a “state” parameter to the Authentication URL. This value must be passed back to Workfront by appending the same value to the Workfront Return URI in the step below.
After logging to the external system (or if the user is already logged in), the user is taken to an “Authentication” page, which explains that Workfront is requesting access to perform a set of actions on the user’s behalf.
If the user clicks the “Allow” button, the browser will redirect to the Workfront Redirect URI , adding “code=<code>
” to the querystring. Per the OAuth2 spec, this token is short lived. The querystring must also have the following, “state=<sent_by_workfront>
”.
Workfront processes this request and makes an API call to the Token Endpoint URL with the authorization code.
The Token Endpoint URL returns a refresh token and access token.
Workfront stores a these tokens and fully provisions the webhook integration for this user.
From this point forward, Workfront will be able to make authorized API calls to the webhook provider. When making these calls, Workfront will send the the access token in the HTTP request header as shown below:
-------------------------------
Authorization: Bearer [access_token]
-------------------------------
If the access token has expired, Workfront will make a call to the Token Endpoint URL to retrieve a new access token then attempt the authorized API call again with the new access token.
Making authorized API calls to a webhook provider using an ApiKey is much simpler than OAuth2. When making an API call, Workfront will simply pass the ApiKey and Workfront username in the HTTP request header:
-------------------------------
apiKey: 12345
username: johndoe@foo.com
-------------------------------
The Webhook provider can use the username to apply user-specific permissions. This works best when both systems connect to LDAP using Single Sign On (SSO).
In addition to using either OAuth2 tokens or an ApiKey for authentication, Workfront can send a predefined set of headers to the webhook provider for every API call. A Workfront administrator can setup set this up when registering or editing a Webook Integration, as described in the section above. See Registering a Webhook Integration.
For example, this can be used for Basic Authentication. To do this, the Workfront administrator would add the following Request Header information in the Custom Integration dialog:
Authorization Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
where QWxhZGRpbjpvcGVuIHNlc2FtZQ== is a base-64 encoded string of “username:password”. See Basic Authentication . Provided that this added, Workfront will pass this in the HTTP request header, in addition to other request headers:
-------------------------------
apiKey: 12345
username: johndoe@foo.com
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
-------------------------------
Below is a list of APIs that the webhook provider should implement in order for document webhooks to work.
Returns the OAuth2 refresh token and access token for an authenticated user. This is invoked once when the the user provisions a Document Provider. Subsequent calls are made to get an updated access token.
HTTP Request POST /any/url
The URL is configurable and corresponds to the Token Endpoint URL value on the custom integration Setup page.
Query Parameters
Name | Required | Description |
---|---|---|
grant_type | yes | Values include "authorization_code" or "refresh_token". The value specified indicates which of the two parameters will be passed to this API call: code or refresh_token. |
code | depends | The authorization code sent to Workfront just after the user clicks the "Grant" button. This is only required when the grant type is "authorization_code". The authorization code should be short lived, generally expiring in 10 minutes or less. |
refresh_token | depends | This is only required when making subsequent calls to retrieve a new access_token, given that the previous access_token as expired. When sending this value set the grant_type parameter to "refresh_token". |
client_id | yes | The Client ID configured in Workfront for this custom integration. |
client_secret | yes | The Client Secret configured in Workfront for this custom integration. |
Response
Name | Type | Description |
---|---|---|
access_token | String | A token used to make authorized API calls on the user's behalf. This should expire to prevent unauthorized API calls. |
refresh_token | String | A long-lived token used to retrieve a new access_token by calling this API method. |
expires_in | long | (optional) The time (in seconds) before the access_token expires, generally 3,600. |
Example
POST /oauth2/token
grant_type=authorization_code
code=d9ac7asdf6asdf579d7a8
client_id=123456
client_secret=6asdf7a7a9a4af
Response
{
"access_token":"ad8af5ad5ads759",
"refresh_token":"9a0h5d87d808ads",
"expires_id":"3600"
}
Returns metadata for the specified file or folder.
URL
GET /metadata?id=[document or folder ID]
Query Parameters
Name | Description |
---|---|
id | The ID of file or folder, as referenced by the webhook provider. This is different than Workfront's document ID. To get the metadata of the root directory, use the value '/'. Note: The maximum length for the ID is 255 characters. |
Response
Name | Type | Description |
---|---|---|
title | String | The name of the document or folder |
kind | String | Specifies if this item is a file or folder ('file' or 'folder') |
id | String | The id of the file or folder. |
viewLink | String | The URL path used by a user to view the document in a browser window. The URL can be hosted by either the document provider or the native external storage provider. |
downloadLink | String | The URL path used by a user to download the document in a browser window. The URL can be hosted by either the document provider or the native external storage provider. |
mimeType | String | The MIME type for the file. (optional) |
dateModified | String | Last time this file was modified (formatted RFC 3339 timestamp) |
size | Long | The size of the file in bytes. (optional) |
readOnly | Boolean | Indicates if this file or folder is read-only to the authenticated user.(optional)
|
Example: https://www.acme.com/api/metadata?id=12345
Response
{
"title":"My Document",
"kind":"file"
"id":"12345",
"viewLink":"https://www.acme.com/viewDocument?id=12345",
"downloadLink":"https://www.acme.com/downloadDocument?id=12345",
"mimeType":"image/png",
"dateModified":"20140605T17:39:45.251Z",
"size": "32554694"
}
Error handling should be consistent across all API calls. See the “Error Handling” section below for details.
Returns metadata for the files and folders for a given folder.
URL
GET /files
Query Parameters
Name | Description |
---|---|
parentId | The folder ID. To get the metadata of the root directory, use the value ‘/’. |
The Document Webhooks API does not currently support pagination.
Response
JSON containing a list of files and folders. The metadata for each item is the same that returned by the /metadata endpoint.
Example: https://www.acme.com/api/files?parentId=123456
Response
[
{
"title":"Folder A",
"kind":"folder",
"id":"2lj23lkj",
"viewLink":"https://www.acme.com/viewDocument?id=2lj23lkj",
"downloadLink":"https://www.acme.com/downloadDocument?id=2lj23lkj",
"mimeType":"",
"dateModified":"20140605T17:39:45.251Z",
"size":""
},
{
"title":"My Document",
"kind":"file",
"id":"da8cj234"
"viewLink":"https://www.acme.com/viewDocument?id=da8cj234",
"downloadLink":"https://www.acme.com/downloadDocument?id=da8cj234",
"mimeType":"image/png",
"dateModified":"20140605T17:39:45.251Z",
"size":"32554694"
},
]
Returns metadata for the files and folders returned from a search. This can be implemented as a full-text search or as a regular database query. Workfront calls the /search endpoint when the user performs a search from the external file browser.
URL
GET /search
Query Parameters
Name | Description |
---|---|
query | The search term or phrase. |
parentId | (optional) The folder ID from which the search executed. Note: This is a placeholder for a future feature in Workfront. Currently, workfront does not pass this parameter. |
The Document Webhooks API does not currently support pagination.
Response
JSON containing a list of metadata for files and folders matching the query. What constitutes a “match” is determined by the webhook provider. Ideally, it should do a full-text search. Doing a filename-based search also works.
Example: https://www.acme.com/api/search?query=test-query
Response
[
{ File/Folder Metadata },
{ File/Folder Metadata }
]
Returns the raw bytes for a document
URL
GET /download
Query Parameters
Name | Description |
---|---|
id |
The document ID. |
Response
The raw bytes of the document.
Example: https://www.acme.com/api/download?id=123456
Returns the raw thumbnail bytes for a document.
URL
GET /thumbnail
Query Parameters
Name | Description |
---|---|
id | The document ID. |
size | The width of the thumbnail |
Response
The raw thumbnail bytes.
Example: https://www.acme.com/api/thumbnail?id=123456
Uploading a file to a document storage provider is a two-step process that requires two separate API endpoint. Workfront begins the upload process by calling /uploadInit . This endpoint returns a document ID which is then passed to /upload when uploading the document bytes. Depending on the underlying document storage system, it may be necessary to create a zero-length document then update the contents of the document later.
Added to version 1.1 of this spec, the document ID and document version ID can be used to retrieve extra information from Workfront. For example, if the document management system wants extra information about the document, the webhook implementation code could use the document ID to retrieve that information using Workfront’s RESTful API. As a good practice, this information could come from custom data fields on the document and it’s containing task, issue, or project.
URL
POST /uploadInit
Query Parameters
Name | Description |
---|---|
parentId | The parent folder ID, as referenced by the webhook provider. |
filename | The name of the document |
documentId | The Workfront document ID (added in version 1.1)
|
documentVersionId | The Workfront document version ID (added in version 1.1) |
Response
The metadata for the file, as defined by the /metadata endpoint.
Example: https://www.acme.com/api/uploadInit?parentId=12345&filename=new-file.png&docu mentId=511ea6e000023edb38d2effb2f4e6e3b&documentVersionId=511ea6e000023edb38d2e ffb2f4e6e3b
Response
[file_metadata]
includes the new document ID used by the document provider.
Uploads the bytes of a document to the webhook provider.
URL
PUT /upload
Query Parameters
Name | Description |
---|---|
id | The document ID, which was just created. |
Request Body
The raw content bytes for the document.
Response
{
"result": "success"
}
or
{
"result": "fail"
}
Example: https://www.acme.com/api/upload?id=1234
[document bytes included in update stream]
Response
{
"result":"success"
}
(Release Date - TBD) Returns information about the service, such as features and capabilities. Workfront will use this information to customize the user interface in Workfront. For example, if the webhook implementation contains some custom actions, the JSON should list those operations in the JSON. Users would then be able to invoke these actions from Workfront.
URL
GET /serviceInfo
Query Parameters
None. In addition, calls to this endpoint should not require authentication.
Response
JSON containing information about this service
Name | Type | Description |
---|---|---|
webhookVersion | String | The webhook version implemented by this service. This is the version number listed at the top of this spec. |
version | String | The internal version number for this service. This number is determined by the webhook service provider and is used for informational purposes only. |
publisher | String | The name of the company providing the webhook implementation. |
availableEndpoints | String | A list containing the API Endpoints implemented by this service. This may be used to ensure that the user interface in Workfront reflect the capabilities offered by the webhook provider. Each item in the list must include the name of the endpoint (such as "search"). |
customActions | String | A list containing the custom operations implemented by this webhook. Each list item includes a name and display name. The display name will appear in the "Document Actions" dropdown in Workfront. Clicking on the item in the dropdown will invoke the action in the webhook by calling the /customAction endpoint. |
Example: https://www.acme.com/api/serviceInfo
Returns
{
"webhook version": "1.2", "version": "1.0", "publisher": "Acme, LLC", "availableEndpoints": ["files", "metadata", "search", "download"
"thumbnail", "uploadInit", "upload" ], "customActions" [
{
"name": "archive", "displayName": "Archive" }, {
"name": "doSomethingElse", "displayName": "Do Something" }, ] }
(Added in version 1.2) Creates a folder in a given directory.
URL
POST /createFolder
Query Parameters
Name | Description |
---|---|
parentId | The folder ID in which the folder should be created |
name | The name of the new folder |
Response
The metadata for the newly created folder, as defined by the /metadata endpoint.
Example: POST https://www.acme.com/api/createFolder
-------------------------------
parentId=1234
name=New Folder
-------------------------------
returns
{"title":"New Folder",
"kind":"folder""id":"5678",
"viewLink":"",
"downloadLink":"",
"mimeType":"",
"dateModified":"20140605T17:39:45.251Z"
"size": ""
}
(Release Date - TBD) Deletes a document or folder with the given ID in the external system. Deleting a folder will also delete its contents.
URL
PUT /delete
Query Parameters
Name | Description |
---|---|
documentId | The document ID to delete |
folderId | The folder ID to delete |
Response A JSON string indicating success or failure, as specified in the Error Handling section below.
Example: PUT https://www.acme.com/api/delete id=1234
returns
{
"status": "success"
}
returns
{
"status": "failure", "error": "File not found"
}
(Release Date - TBD) Renames a document or folder with the given ID in the external system.
URL
PUT /rename
Query Parameters
Name | Description |
---|---|
id | The document or folder ID to rename |
name | The new name of the document or folder |
Response
A JSON string indicating success or failure, as specified in the Error Handling section below.
Example:
PUT https://www.acme.com/api/rename
-------------------------------
id=1234
name=Folder B
-------------------------------
{
"status": "success"
}returns
{
"status": "failure", error: "Folder cannot be renamed because a folder with that name already exists."
}
(Release Date - TBD) This endpoint will allow a Workfront user (or perhaps an automated workflow event) to perform an action in the external system. The /customAction endpoint accepts a “name” parameter, which allows the webhook provider to implement multiple custom operations.
The webhook provider registers custom actions with Workfront by including the actions in the /serviceInfo response under customActions. Workfront loads this list when setting up or refreshing the webhook provider under Setup > Documents > Custom Integrations.
Users can trigger the custom action by selecting the section under “Document Actions”
URL
GET /customAction
Query Parameters
Name | Description |
---|---|
name |
The identifier specifying the type of action to be performed. This value corresponds to one of the customAction values listed returned by the /serviceInfo endpoint. |
documentId | The workfront document ID for which the action is being performed. |
documentVersionId | The workfront document version ID for which the action is being performed. |
Response
A JSON string indicating success or failure, as specified in the Error Handling section below. On failure (i.e. status = “failure”), Workfront will display the provided error message to the user.
Example: https://sample.com/webhooks/customName?name=archive&documentId=5502082c003a4f30 ddec2fb2b739cb7c&documentVersionId=54b598a700e2342d6971597a5df1a8d3
response
{
"status": "success"
}
Problems may arise when processing API requests. This should handled in a consistent way across across all API endpoints. When an error occurs, the webhook provider do the following:
Include an error code in the response header. Error codes include:
Describe the error in the response body using the following format:
{
"status": "error"
"error": "Sample error message"
}
To verify that your document webhook implementation works correctly, run the following tests. These are manual tests that go through the Workfront web interface and indirectly hit the endpoints for your webhook implementation.
To run these tests you will need the following:
These tests also assume that you’ve already registered your Document Webhook instance in Workfront under Setup > Documents > Custom Integrations.
Tests the Authentication URL and Token Endpoint URL for OAuth-based Webhook providers.
Tests the following endpoints: /metadata (specifically the viewLink)
Tests the following endpoints: /metadata (specifically the viewLink)
Tests the following endpoints: /metadata (specifically the downloadLink)
Tests the following endpoints: /search
Tests the following endpoints: /files, /uploadInit, /upload
Tests the following endpoints: /thumbnail
Tests the following endpoints: /download
Tests the following endpoints: Token Endpoint URL
Currently, the Send To… isn’t available for linked documents. This will be added by Workfront. You can test the /download endpoint by hitting the endpoint manually using a REST client, such as Postman. Alternatively, the /download endpoint can be tested by generating a digital proof. To enable, digital proofing please contact Workfront.
Version 1.0 (Release Date - May, 2015)
Version 1.1 (Release Date - June, 2015)
Version 1.2 (Release Date - October, 2015)