Webhooks

Aprimo Cloud webhooks are lightweight, event-driven HTTPS callouts from Aprimo Cloud. When certain events happen in Aprimo, such as the creation of a record or reaching a certain point in a workflow, a webhook can make an HTTPS call to your web service and provide a lightweight message in JSON format. An HMAC will also be provided to validate that the message came from Aprimo Cloud. Webhooks contain only contextual information to understand what event triggered the callout. If this information is not enough for your integration, you can call back into the REST API to gather the additional data needed by your integration.

Webhooks may be enabled for specific objects to be triggered on record creates, updates, and deletes, or may be triggered at specific points in a workflow. Webhooks will call out for every event triggered. It is up to the receiving service to determine whether the message should require action. For example, if a webhook is set up on activity creation, any created activity will fire a webhook regardless of the activity type or any other metadata field.

Important: Unsuccessful WebHook Callouts
If a successful response is not returned to the WebHook publisher within less than 30 seconds, a retry of the WebHook will be attempted up to 30 times with an increasing interval between retries spanning up to 24 hours. Should it run out of retry attempts, the WebHook will be classed to have failed.

Should a given WebHook subscription encounter 5 failures it will be invalidated and all the system administrators informed via in-app messaging so as to allow them to rectify the problem and then re-validate the subscription from within WebHook Administration. WebHooks can now be retried manually from within the Integration Log.

Webhook Payload

Webhook callouts are HTTP POST requests to a URL that you specify.

The payload of a webhook looks like this *:

{
   "CalloutLocation":2,
   "DatasourceId":6011,
   "CalloutType":9952,
   "Title":"object-update",
   "ObjectTypeId":9952,
   "ObjectResourceName":"projects",
   "ObjectId":87701,
   "CreatingUserId":1,
   "RetryCount":0,
   "Body":null,
   "Id":"9672c836-8b9c-44e6-bfbe-c8d028ba963a",
   "EventTime":"2016-10-12T13:19:07",
   "EventId":"7f81c80f-200e-4d45-96d1-f041bbc350ff",
   "ParentEventId": "7f81c80f-200e-4d45-96d1-f041bbc350ff"
}

* “Body”: null tag null value is not applicable for task status action callout location 100

*”ParentEventId”: ParentEventId is set if you attempt to retry a webhook. The ParentEventId is set to the EventId of the previous attempt.

The fields sent are defined as followed:

  • CalloutLocation indicates the type of webhook in integer form. Title is the readable name for the CalloutLocation. The following titles and calloutlocations are supported today, and may be set as Webhook Source Location when configuring webhooks.
Title CalloutLocation
Object Created 1
Object Updated 2
Object Deleted 3
Task Status Action Fired 100
Project Started 102
Project Paused 103
Project Resumed 104
Project Closed 105
Project Cancelled 106
Project Role Changed 107
Commitment Approval Approved 120
Commitment Approval Rejected 121
Commitment Cancelled 122
Forecast Changed on Activity 123 (Rel. 109)
Segmentation Started 140
Segmentation Completed 141
Segmentation Failed 142
Segment Completed 143
Program Proposal Submitted 160
Activities Added or Removed in a Program 161
Activity Linked or Unlinked in Content Plan 162
SSO User Created 500
SSO User Updated 501
  • DatasourceId – An internal value used by Aprimo for diagnostic purposes. This can be ignored.
  • CalloutType – The Aprimo Object ID for creates, updates, or deletes on an Aprimo object, or an Aprimo webhook ID if triggered from a task status action.
  • ObjectTypeId -The Aprimo Object ID for creates, updates, or deletes on an Aprimo object, or 9963 for task status actions. (See below list for supported objects).
  • ObjectId – The ID of record that triggered the webhook.
  • CreatingUserId: The Aprimo User Id of the user who triggered the event. This may be an actual user of the system or a service user if the event was triggered by an automated process.
  • RetryCount: The retry count of this message.
  • Body Id: An ID used by Aprimo for diagnostic purposes. This can be ignored.
  • EventTime: The time the event originally occurred in UTC.
  • EventId: A unique ID for the event, consistent through any retries.

Additionally, task status actions will include the following extra fields in the body:

  • Project_Id: The project ID associated with the task that triggered the status action.
  • Step_type: The workflow step type associated to the task. Different step types may require different REST API calls to get additional data (for example, a review task may have more information than a basic task).
  •  Test_mode: Test mode may be turned on when configuring a workflow status action in the Aprimo workflow designer. This can be used by the receiving service to decide to take actions if workflows are still being tested.

The payload of a task status action webhook looks like this:

{
   "CalloutLocation":100,
   "DatasourceId":6011,
   "CalloutType":1,
   "Title":"task-status-action",
   "ObjectTypeId":9963,
   "ObjectResourceName":"tasks",
   "ObjectId":87701,
   "CreatingUserId":1,
   "RetryCount":0,
   "Body":"{"project_id":1000, "step_type":9, "status":"Approved", "test_mode":0}",
   "Id":"9672c836-8b9c-44e6-bfbe-c8d028ba963a",
   "EventTime":"2016-10-12T13:19:07",
   "EventId":"7f81c80f-200e-4d45-96d1-f041bbc350ff"
}

 

The value of the Body attribute is a string.

Integration Log – Important Developer Note
The integration log and the WebHook publisher service, whilst intrinsically linked, may differ in the order of displayed JSON field structure constituting the payload. The content will be the same, but prominence may be given to different attributes within. They of course will always be linked by the various Event ID GUID attributes.

Retries

If a webhook callout receives any HTTP Status in the HTTP Response other than a response in the ‘success’ range (200 to 299), it will queue up a webhook for a retry. The first retry will happen after 1 minute, followed by 2 minutes, 5 minutes, 7 minutes, 15 minutes, 30 minutes, and 60 minutes, at which point retries will continue every 60 minutes until 24 hours have passed. It is recommended that you return a response from the webhook as soon as possible and do any additional processing asynchronously in order to avoid timeouts and extra retries where they are not necessary.

Logging

In order to see what webhooks have triggered, you may navigate to the integration log under Aprimo’s System Tools section to see generated webhooks. If you do not see this section, create a support ticket asking for the integration-log feature flag to be enabled for your tenant.

HMAC

It is advised that when you receive a webhook, you validate it with the HMAC to ensure its authenticity. The HMAC will appear in an HTTP Header called X-SH1. To validate the message, use the secret value you provided as a key to generate the base64 encoded representation of the HMAC of the HTTP body content using the HMACSHA256 algorithm and compare it to the header value. For valid messages, these values should match.  You can find details on the Microsoft implementation of the HMACSHA256 algorithm here https://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha256(v=vs.110).aspx

Additionally, the following sample C# code illustrates how to calculate this HMAC

using System.Security.Cryptography;
using System.Text;
static string CalculateAprimoWebhookHMAC(string secret, string httpBodyContent)
{
  var payload = Encoding.UTF8.GetBytes(httpBodyContent);
  var key = Encoding.UTF8.GetBytes(secret);
  using (var hash = new HMACSHA256(key))
  {
    return System.Convert.ToBase64String(hash.ComputeHash(payload));
  }
}

Object Support for Object Created, Updated, and Deleted

If your Webhook Source Location is Object Create, Object Updated, or Object Deleted then only the following objects are supported. Format is Object Name (Webhook Sub Type ID)

  • Activity (1)
  • Activity Cells (10100)
  • Activity Forecasts (6113)
  • Activity Offers (9714)
  • Activity Proposals (3)
  • Attachments (6214)
  • Brands (10065)
  • Calendar Events (6069)
  • Clients (10056)
  • Commitments (6135)
  • Content Plan (5000)
  • Currency Exchange Rates (10270)
  • Digital Assets (from Digital Asset Library) (39)
  • Expense Categories (10324)
  • Funding Accounts (10235)
  • Generic Object Alpha (10891)
  • Generic Object Bravo (10892)
  • Generic Object Charlie (10893)
  • Generic Object Delta (10894)
  • Generic Object Echo (10895)
  • Incentives (10121)
  • Invoices (6)
  • Journal Vouchers (10345)
  • Notes (6202)
  • Offers (9709)
  • Products (10129)
  • Programs (2)
  • Projects (9952)
  • Roles (9944)
  • Suppliers (11)
  • Tasks (9963)
  • Treatments (9711)
  • Users (12)

Creating, updating, and deleting webhooks

Webhooks can be created and managed inside of the application UI under System Tools->Integration->Webhook Subscriptions.

Designing for Webhooks

A key design concept to understand is that webhooks are not guaranteed to be delivered in chronological order of the events which triggered them. For example, if a user creates a record, then updates it, but the create message fails in transit to the receiving service and is queued for retry, but the update message does not, you may receive the update message prior to the create message. The design of your integration should always assume that messages can be received out of order, and it’s best practice to always call back into the REST API to get the latest real-time data out of Aprimo when receiving a webhook message and reacting appropriately.

It is also important to note that unless the WebHook publisher receives a successful reply i.e. a status 200 OK response within less than 30 seconds, it will assume the callout has failed and will automatically enqueue a retry attempt. You should always respond immediately upon receipt of the http callout and indicate successful transmission.

Please do not provide status responses to the publisher from other REST API calls you may be making to other routes within Aprimo as they are not relevant to the operation of the service.

Integration Callouts in Workflows

Integration Callouts on a workflow are a special type of WebHook which fire a message to an external system when a status action event occurs within that Workflow’s execution, i.e. a task goes to In Progress status. These are also known as Task Status Action WebHooks, source location 100 in the tables above. These will also have a bit more information added to the callout to specify some additional information often required by these type of events, such as Project Id, Step Type etc. A task status action example is shown in the payload section of this page.

You create these in the normal manner via System Administration > Integration > WebHook Subscriptions.

For the option “WebHook Source Location” – Choose Task Status Action, which will cause a new field called Title to appear. This title is what will appear under the Integration Callout section of workflows as a selectable option.

For any workflow and its associated status actions, you will then have the option of “attaching” the WebHook to the particular event. When that event occurs (the task status change) it will contact the subscription end point you have specified in your WebHook as per normal callout operation.

After creation within administration, please note it can take up to 15 minutes for the WebHook subscription to be fully available and ready for publication (use).

mTLS Security in webhooks

Aprimo Productivity Management webhooks support optional mTLS authentication. When enabled, a single global cert is used to sign requests to verify they come from Aprimo. Optionally, you can validate the certificate on your end using Aprimo’s public key certificate. In order to get a copy of this certificate, contact your Aprimo representative.

To enable this feature for your tenant, enable the Send mTLS Certificate With WebHooks system parameter found under Administration->Configuration->System Parameters->System->Security. Note that it may take up to 15 minutes for this parameter to start taking effect.