How do I create a webhook to call a third party API when an event occurs?

Providing you are a LUSID user with sufficient access control permissions, you can create a webhook notification to call a third party (that is, non-LUSID) API when an event you have subscribed to occurs. For example, your webhook could call the Atlassian Create issue API to create a JIRA when the LUSID PortfolioCreated event occurs.

Note the following:

  • You must have already subscribed to the event you want to attach the webhook notification to.

  • You can only call API endpoints that use PUT, POST or DELETE verbs.

  • You do not have access to API responses, so calls to API endpoints that get or list data are ineffective.

  • We guarantee notifications are delivered once but in your implementation you should guard against them being delivered more than once.

  • Note that alternatively your webhook can call a LUSID API.

Using the Notification REST API

Currently, you can create one notification per API call.

  1. Upload your credentials for the third party API to the Configuration Store. This can either be a Bearer Token or a Basic Authentication username and password.

  2. Obtain an API access token for the operations below.

  3. Call the CreateNotification API, passing in your API access token and:

    • The scope and code of the subscription to attach it to.

    • A displayName and unique notificationId.

    • A Type of Webhook.

    • A HttpMethod of either PUT, POST or DELETE.

    • A Url that constitutes a full path to the resource, for example https://acmecorp.atlassian.net/rest/api/3/issue.

    • An AuthenticationType of either BearerToken if the receiving service supports OAuth 2.0, or else BasicAuth.

    • An AuthenticationConfigurationItemPaths object that specifies the path to the access token or basic authentication credentials uploaded to the Configuration store. For example, to reference a bearer token uploaded to external-services/jira in the Personal area of the Configuration Store:

      "BearerToken": "config://personal/00u91lo2d7X42sdse88/external-services/jira/api-token"

      If the token scheme is not Bearer, use the BearerScheme key to locate an appropriate scheme uploaded to the Configuration Store.

      To reference Basic Authentication credentials uploaded to the same location:

      "Username": "config://personal/00u91lo2d7X42sdse88/external-services/jira/username",
      "Password": "config://personal/00u91lo2d7X42sdse88/external-services/jira/password"

      To find out the exact syntax of a config:// path, call the Configuration Store GetConfigurationItem API for that item.

    • A ContentType of Json.

    • A Content object that contains the expected payload for the API.

    Consider the following example, of a webhook notification attached to a subscription with scope PortfolioEvents and code PortfolioCreated. Note the use of event attributes in mustache templates as placeholders for values generated by the event each time it occurs:

    curl -X POST "https://<your-domain>.lusid.com/notification/api/subscriptions/PortfolioEvents/PortfolioCreated/notifications" 
        -H "Authorization: Bearer <your-API-access-token>" 
        -H "Content-Type: application/json"
        -d '{
              "notificationId": "PortfolioCreatedJiraWebhook",
              "displayName": "PortfolioCreatedWebhookNotification",
              "description": "Create JIRA for new portfolio",
              "notificationType": {
                "Type": "Webhook",
                "HttpMethod": "Post",
                "Url": "https://acmecorp.atlassian.net/rest/api/3/issue",
                "AuthenticationType": "BearerToken",
                "AuthenticationConfigurationItemPaths": {
                  "BearerToken": "config://personal/00u91lo2d7X42sdse88/external-services/jira/api-token"
                },
                "ContentType": "Json",
                "Content": {
                   "update": {},
                   "fields": {
                     "summary": "Portfolio with ID {{Body.portfolioScope}}/{{Body.portfolioCode}} created on {{Header.timestamp}} - action required",
                     "parent": {
                       "key": "PROJ-123"
                     },
                     "issuetype": {
                       "id": "10000"
                     }
                   }
                }
              }   
            }'
    

    The response is as follows. Note you can use the id of the notification to reference it again in subsequent API calls:

    {
      "notificationId": "PortfolioCreatedJiraWebhook",
      "displayName": "PortfolioCreatedWebhookNotification",
      "description": "Create JIRA for new portfolio",
      "notificationType": {
        "ContentType": "Json",
        "Content": {
          "update": {},
          "fields": {
            "summary": "{{PortfolioName}} with ID {{PortfolioScope}}/{{PortPortfolio}} created on {{PortfolioCreated}} - action required",
            "parent": {
              "key": "PROJ-123"
            },
            "issuetype": {
              "id": "10000"
            }
          }
        },
        "type": "Webhook",
        "httpMethod": "Post",
        "url": "https://acmecorp.atlassian.net/rest/api/3/issue",
        "authenticationType": "BearerToken",
        "authenticationConfigurationItemPaths": {
          "BearerToken": "config://personal/00u91lo2d7X42sdse88/external-services/jira/api-token"
        }
      },
      "createdAt": "2023-07-21T13:59:58.2881300+00:00",
      "userIdCreated": "00u91lo2d7X42sdse2p7",
      "modfiedAt": "2023-07-21T13:59:58.2881300+00:00",
      "userIdModified": "00u91lo2d7X42sdse2p7",
      "href": "https://<your-domain>.lusid.com/notification/api/subscriptions/PortfolioEvents/PortfolioCreated/notifications/PortfolioCreatedJiraWebhook"
    }

Using the LUSID web app

<Coming soon>