Webhooks

The Webhook resource

Webhooks provide a mechanism to integrate Scalr with external API’s. Webhooks are triggered by Events which causes Scalr to send an HTTP POST payload to the endpoint associated with the webhook.

Webhooks can be used to trigger any action in any external system that has an API or programmable interface. The Endpoint will typically point to a server that processes the HTTP POST request and makes the onward calls to the external API.

Webhooks can be created in environments or in specific workspaces.

Example:

POST /services/58320402 HTTP/1.1
Host: hooks.example.com
Content-Type: application/json
Content-Length: 935
Date: 2020-11-25T00:43:38+0000
X-Scalr-Delivery-Id: wd-t6v0hrnn58vu4m0
X-Signature: 5782c2fa7c38ddc45efd8b7497ac1c9c91ae90fae2fa06148b69bba4c2e22869

{
  "payload_version": 1,
  "event_name": "run:needs_attention",
  "run": {
    "id": "run-t6v0g8prd9qi2h0",
    "message": "Update variables.tf",
    "status": "policy_checked",
    "source": "ui",
    "url": "https://my.scalr.io/#/workspaces/runs/dashboard?runId=run-t6v0g8prd9qi2h0",
    "created_at": "2020-11-25T00:42:15",
    "updated_at": "2020-11-25T00:43:38",
    "created_by": {
      "id": "user-stp8qjcvjljlo1o",
      "username": "me@example.com",
      "email": "me@example.com"
    }
  },
  "webhook": {
    "id": "wh-t6v0g1l0dlqhh58",
    "name": "Data Platform"
  },
  "workspace": {
    "id": "ws-t5hft7e7v366rd0",
    "name": "my-example",
    "url": "https://my.scalr.io/#/workspaces/dashboard?workspaceId=ws-t5hft7e7v366rd0"
  },
  "environment": {
    "id": "env-sfuari395m7sck1",
    "name": "my-development",
    "url": "https://my.scalr.io/#/15986/17348/dashboard"
  },
  "variables": {
    "foo": "bar"
  }
}

Scalr adds a cryptographic signature to Webhook notifications in order for you to be able to validate that they were indeed generated by Scalr.

To validate Webhook notification, follow this procedure:

  • Obtain the secret_key for your Endpoint.

  • When receiving a Webhook payload, compute its signature using the following algorithm (see below for code samples)

    • Concatenate the JSON payload and the Date header

    • Compute a HMAC digest of the concatenated message, using the SHA-256 algorithm

    • Retrieve the hexadecimal value of the HMAC digest. This is the signature.

  • Compare the signature you computed to the one in the X-Signature HTTP Header. For maximum security, ensure you perform a constant-time comparison.

    • If the signatures match, the message is authentic, and was indeed sent by Scalr

    • If the signatures do not match, the message is a forgery, and was not sent by Scalr

To compute a Webhook notification signature in Bash, use the following algorithm. We assume that the $payload variable contains the request JSON payload, that $timestamp contains the Date Header, and that $secret_key is your Endpoint’s secret-key.

canonical_string="${payload}${timestamp}"
signature=$(echo -n $canonical_string | openssl dgst -sha256 -hmac $secret_key | awk '{ print $2}')

Key path

Description

type* (string)

Available values: webhooks

id (string)

attributes.enabled (boolean)

Webhook can be turned off by setting to false.

attributes.last-triggered-at (string)

The Date/Time of the last notification.

attributes.name* (string)

The name of the webhook. Use your target application/component name for better discoverability.

attributes.permissions (object)

relationships.account (object)

The account this webhook belongs to.

relationships.account.data.type* (string)

Available values: accounts

relationships.account.data.id* (string)

relationships.endpoint* (object)

The Endpoint this webhook is delivered to.

relationships.endpoint.data.type* (string)

Available values: endpoints

relationships.endpoint.data.id* (string)

relationships.environment (object)

The environment this webhook belongs to.

relationships.environment.data.type* (string)

Available values: environments

relationships.environment.data.id* (string)

relationships.events (object)

The list of events this webhook will be notifed about. Use List Event Definitions to obtain the list of all available events.

relationships.events.data* (array)

relationships.workspace (object)

The optional workspace this webhook belongs to.

relationships.workspace.data.type* (string)

Available values: workspaces

relationships.workspace.data.id* (string)

links.self (string)

List Webhooks

GET /api/iacp/v3/webhooks

This endpoint lists webhooks.

Query Parameters
  • filter[enabled] (string) – Enabled true|false only webhooks

  • filter[workspace] (string) – The ID of the Workspace

  • filter[environment] (string) – The ID of the Environment

  • filter[account] (string) – The ID of the Account

  • filter[event] (string) – The ID of the Event definition

  • page[number] (string) – Page number

  • page[size] (string) – Page size

  • include (array) – The comma-separated list of relationship paths. (Available values: endpoint, workspace)

  • sort (array) – The comma-separated list of attributes. (Available values: name)

  • query (string) – Query string

Example Request:

GET /api/iacp/v3/webhooks HTTP/1.1
Host: my.scalr.io
Prefer: profile=preview
Status Codes
  • 200 OK – Success.

  • 404 Not Found – Account, environment, or workspace not found or user unauthorized to perform action.

  • 4XX – Client error.

  • 5XX – Server error.

Create Webhook

POST /api/iacp/v3/webhooks

Create a new webhook bounded to the account, environment, or workspace.

Request body:

Key path

Description

data.type* (string)

Available values: webhooks

data.id (string)

data.attributes.enabled (boolean)

Webhook can be turned off by setting to false.

data.attributes.name* (string)

The name of the webhook. Use your target application/component name for better discoverability.

data.relationships.account (object)

The account this webhook belongs to.

data.relationships.account.data.type* (string)

Available values: accounts

data.relationships.account.data.id* (string)

data.relationships.endpoint* (object)

The Endpoint this webhook is delivered to.

data.relationships.endpoint.data.type* (string)

Available values: endpoints

data.relationships.endpoint.data.id* (string)

data.relationships.environment (object)

The environment this webhook belongs to.

data.relationships.environment.data.type* (string)

Available values: environments

data.relationships.environment.data.id* (string)

data.relationships.workspace (object)

The optional workspace this webhook belongs to.

data.relationships.workspace.data.type* (string)

Available values: workspaces

data.relationships.workspace.data.id* (string)

Example Request:

POST /api/iacp/v3/webhooks HTTP/1.1
Host: my.scalr.io
Content-Type: application/vnd.api+json
Prefer: profile=preview

{
  "data": {
    "type": "webhooks",
    "attributes": {
      "name": "Data Platform",
    },
    "relationships": {
      "endpoint": {
        "data": {
          "type": "endpoints",
          "id": "ep-t1jvkud6virv9fo"
        }
      },
      "environment": {
        "data": {
          "type": "environments",
          "id": "env-sfuari395m7sck1"
        }
      },
      "events": {
        "data": [
          {
            "type": "event-definitions",
            "id": "run:completed"
          }
        ]
      }
    }
  }
}
Status Codes
  • 201 Created

    The webhook was created.

    Example Respone:

    HTTP/1.1 201 Created
    Content-Type: application/vnd.api+json
    Preference-Applied: profile=preview
    
    {
      "data": {
        "attributes": {
          "enabled": true,
          "last-triggered-at": null,
          "name": "Data Platform",
          "permissions": {
            "webhooks:delete": true,
            "webhooks:update": true
          }
        },
        "id": "wh-t6tf3tsveh411rg",
        "links": {
          "self": "https://my.scalr.io/api/iacp/v3/webhooks/wh-t6tf3tsveh411rg"
        },
        "relationships": {
          "account": {
            "data": {
              "id": "acc-t2fcrq6h1v3nf0g",
              "type": "accounts"
            }
          },
          "endpoint": {
            "data": {
              "id": "ep-t1jvkud6virv9fo",
              "type": "endpoints"
            }
          },
          "environment": {
            "data": {
              "id": "env-sfuari395m7sck1",
              "type": "environments"
            }
          },
          "events": {
            "data": [
              {
                "id": "run:completed",
                "type": "event-definitions"
              }
            ]
          },
          "workspace": null
        },
        "type": "webhooks"
      },
      "included": null,
      "meta": null
    }
    

  • 404 Not Found – Relationship not found, or user unauthorized to perform action.

  • 422 Unprocessable Entity – Invalid arguments.

  • 4XX – Client error.

  • 5XX – Server error.

Delete a Webhook

DELETE /api/iacp/v3/webhooks/{webhook}
Parameters
  • webhook (string) – The ID of the webhook to delete.

Status Codes
  • 204 No Content – Successfully deleted the webhook.

  • 404 Not Found – Webhook not found, or user unauthorized to perform action.

  • 4XX – Client error.

  • 5XX – Server error.

Get a Webhook

GET /api/iacp/v3/webhooks/{webhook}

Show details of a specific webhook.

Parameters
  • webhook (string) – The ID of the webhook.

Query Parameters
  • include (array) – The comma-separated list of relationship paths. (Available values: endpoint, workspace)

Example Request:

GET /api/iacp/v3/webhooks/{webhook} HTTP/1.1
Host: my.scalr.io
Prefer: profile=preview
Status Codes
  • 200 OK – Success.

  • 404 Not Found – Webhook not found or user unauthorized to perform action.

  • 4XX – Client error.

  • 5XX – Server error.

Update Webhook

PATCH /api/iacp/v3/webhooks/{webhook}
Parameters
  • webhook (string) – The ID of the webhook to update.

Request body:

Key path

Description

data.type* (string)

Available values: webhooks

data.id (string)

data.attributes.enabled (boolean)

Webhook can be turned off by setting to false.

data.attributes.name* (string)

The name of the webhook. Use your target application/component name for better discoverability.

data.relationships.account (object)

The account this webhook belongs to.

data.relationships.account.data.type* (string)

Available values: accounts

data.relationships.account.data.id* (string)

data.relationships.endpoint* (object)

The Endpoint this webhook is delivered to.

data.relationships.endpoint.data.type* (string)

Available values: endpoints

data.relationships.endpoint.data.id* (string)

data.relationships.environment (object)

The environment this webhook belongs to.

data.relationships.environment.data.type* (string)

Available values: environments

data.relationships.environment.data.id* (string)

data.relationships.workspace (object)

The optional workspace this webhook belongs to.

data.relationships.workspace.data.type* (string)

Available values: workspaces

data.relationships.workspace.data.id* (string)

Example Request:

PATCH /api/iacp/v3/webhooks/{webhook} HTTP/1.1
Host: my.scalr.io
Content-Type: application/vnd.api+json
Prefer: profile=preview

{
    "data": {
        "attributes": {
            "enabled": true,
            "name": "string"
        },
        "id": "string",
        "relationships": {
            "account": {
                "data": {
                    "id": "string",
                    "type": "accounts"
                }
            },
            "endpoint": {
                "data": {
                    "id": "string",
                    "type": "endpoints"
                }
            },
            "environment": {
                "data": {
                    "id": "string",
                    "type": "environments"
                }
            },
            "workspace": {
                "data": {
                    "id": "string",
                    "type": "workspaces"
                }
            }
        },
        "type": "webhooks"
    }
}
Status Codes