# Post-Load Webhook Reference

Information note

**Post-load notifications are an upgraded feature**

Post-load notifications are an upgraded feature that’s available during the free trial or for customers on an Advanced or Premium plan.

Post-load hooks allow you to configure a webhook that fires each time data is loaded into your existing destination.

Using post-load hooks, you can extend Stitch and automate dependent processes. For example: Trigger downstream processing in SQL, an Amazon Web Services Lambda function, Talend Cloud jobs, or any other system that can be controlled with an HTTP request.

## Set up a post-load hook

You can configure a post-load hook in two ways:

1. [In the Stitch app](https://help.qlik.com/en-US/stitch/account-security/notifications/post-load-notifications#manage-post-load-hooks)
2. [Via the Connect API](https://help.qlik.com/en-US/stitch/developers/stitch-connect/api#notifications--section), if your Stitch plan includes API access

You can configure up to 10 post-load hooks.

## Webhook triggers

Post-load hooks are sent on a per-integration, per-table basis to each configured post-load webhook URL. The post-load webhook must have a status of **Enabled** in order for Stitch to send requests.

If multiple tables are set to replicate for an integration, Stitch will send a request for each table every time data is successfully loaded or rejected.

If the load for a table fails, a post-load webhook will not be sent. For example: The Stitch database user has insufficient database privileges. In this scenario, Stitch will send an [email notification](https://help.qlik.com/en-US/stitch/account-security/notifications#notification-reference).

## Security

* [Webhook URL requirements](https://help.qlik.com/en-US/stitch/developers/webhooks#webhook-url-requirements)

* [IP whitelisting](https://help.qlik.com/en-US/stitch/developers/webhooks#ip-whitelisting)

### Webhook URL requirements

To be compatible with Stitch post-load hooks, the service must provide a properly formatted HTTPS webhook URL. For example: `https://your-webhook-provider.com/webhooks`

If the URL doesn’t use HTTPS, you’ll receive an `Invalid URI` error when you attempt to add the webhook in Stitch.

### IP whitelisting

Post-load notification webhook requests will originate from one of the [IP addresses](https://help.qlik.com/en-US/stitch/security/stitch-ip-addresses) for your Stitch account’s [data pipeline region](https://help.qlik.com/en-US/stitch/security/supported-data-pipeline-regions).

To add an additional layer of security, or if the service you’re using requires it, you can whitelist the Stitch IP addresses for your account’s data pipeline region. This ensures that only requests sent from Stitch will be accepted and processed by the webhook service you’re using.

## Retries

If the service you’ve configured to receive post-load hooks encounters problems, **Stitch will attempt to re-send the notification up to five times**. Stitch will re-try when the following occurs:

* The request fails to connect
* The request doesn’t receive a response after 30 seconds (timeout)
* The request recieves a response code other than `2xx`

If the notification can’t be delivered after the maximum number of retries, Stitch will send an [email notification](https://help.qlik.com/en-US/stitch/account-security/notifications#undeliverable-post-load) immediately after the last retry fails. Replaying post-load hooks isn’t currently supported.

**Note**: A load is still considered successful even if the post-load notification webhook fails.

## Webhook payload

* [Header](https://help.qlik.com/en-US/stitch/developers/webhooks#payload-header)

* [Request format](https://help.qlik.com/en-US/stitch/developers/webhooks#request-format)

### Header

Post-load notification webhook requests are `POST` requests with a `User-Agent` of `StitchLoadingWebhook`. For example:

```
Example request header
```

```
curl -X "POST" "https://your-webhook-service.com/webhook" \
     -H 'Content-Type: application/json' \
     -H 'User-Agent: StitchLoadingWebhook'
```

**Note**: At this time, custom request headers are not supported.

### Request format

Post-load notification webhook requests have a JSON payload in the body, similar to the following example.

Refer to the [Request body properties section](https://help.qlik.com/en-US/stitch/developers/webhooks#request-body-properties) for attribute descriptions:

```

```

```
{  
   "version":"1.0",
   "minimum_sdc_batched_at":"2019-07-15T14:45:08.026Z",
   "integration_name":"shopify",
   "new_version":false,
   "source_root_table_name":"orders",
   "destination_root_table_name":"orders",
   "table_version":0,
   "tables":[  
      {  
         "source_table_name":"orders",
         "destination_table_name":"orders",
         "num_rows":100,
         "num_rows_rejected":11,
         "s3_objects":[  
            "stitch-s3-bucket/orders/0_1563294550038.jsonl"
         ],
         "primary_keys":[
            "order_id"
         ],
         "bookmark_metadata":[  
            {  
               "key":"updated_at",
               "max_value":"2018-12-31T00:00:00Z",
               "min_value":"2018-12-31T00:00:00Z"
            }
         ],
         "max_time_extracted":"2019-07-15T14:43:09.030Z"
      }
   ]
}
```

## Request body properties

A post-load notification webhook object is composed of the following:

* [Top-level properties](https://help.qlik.com/en-US/stitch/developers/webhooks#post-load-webhook-object-top-level-properties)

* [Table object properties](https://help.qlik.com/en-US/stitch/developers/webhooks#post-load-webhook-table-object)

* [Bookmark metadata object properties](https://help.qlik.com/en-US/stitch/developers/webhooks#post-load-webhook-bookmark-metadata-object)

### Top-level properties

A post-load notification webhook object contains the following top-level properties:

| **Attribute name** | **Type** | **Description** |
| --- | --- | --- |
| **version** | string | The version of the post-load webhook. |
| **minimum\_sdc\_batched\_at** | timestamp | Timestamp indicating when Stitch loaded the batch the record was a part of into the destination. |
| **integration\_name** | string | The name of the integration. |
| **new\_version** | boolean | If `true`, the load involved a `TRUNCATE` command for the table. |
| **source\_root\_table\_name** | string | The root name of the table in the data source. |
| **destination\_root\_table\_name** | string | The root name of the table in the destination. |
| **table\_version** | integer | The version of the table. |
| **tables** | array | An array of [`table` objects](https://help.qlik.com/en-US/stitch/developers/webhooks#post-load-webhook-table-object). |

### Table object properties

The `tables` object contains info about the table being loaded. This list will contain at least one object, but may contain more if there are subtables.

**Note**: If using a destination [that doesn’t natively support nested structures](https://help.qlik.com/en-US/stitch/destinations/choosing-a-stitch-destination#nested-data-structures), this list will include subtables created as a result of denesting JSON arrays. Refer to the [Nested JSON data structures guide](https://help.qlik.com/en-US/stitch/replication/loading/understanding-loading-row-usage-for-nested-data-structures) for more info.

A `table` object contains the following properties:

| **Attribute name** | **Type** | **Description** |
| --- | --- | --- |
| **bookmark\_metadata** | array | An array of [`bookmark_metadata` objects](https://help.qlik.com/en-US/stitch/developers/webhooks#post-load-webhook-bookmark-metadata-object).<br><br>**Note**: If all rows for the table have been rejected, this property will be `null`. |
| **destination\_table\_name** | string | The name of the table in the destination.<br><br>**Note**: If this is a subtable created from denesting an array, this value will be the `source_root_table_name` appended with the `source_table_name`.<br><br>For example: If `orders.order_items`, this value would be `orders__order_items`. |
| **max\_time\_extracted** | timestamp | A timestamp indicating the time that the last row was extracted for the table. |
| **num\_rows** | integer | The total number of rows that were successfully loaded into the destination for the table.<br><br>**Note**: If all rows for the table have been rejected, this value will be `0`. |
| **num\_rows\_rejected** | integer | If rows were rejected, this value will indicate the total number of rows that were rejected for the table. Refer to the [Rejected records log guide](https://help.qlik.com/en-US/stitch/replication/loading/system-tables-columns/rejected-records-system-table) for more info. |
| **primary\_keys** | array of strings | **Applicable only if using an Amazon S3 destination.** The names of the table’s Primary Keys columns. |
| **s3\_objects** | array of strings | **Applicable only if using an Amazon S3 destination.** The table’s corresponding Object Key in the S3 bucket. This is determined by [the **Object Key** setting](https://help.qlik.com/en-US/stitch/destinations/amazon-s3/connecting-an-amazon-s3-data-warehouse-to-stitch#define-s3-object-key) in the **Destination** page of Stitch.<br><br>For example: `stitch-s3-bucket/orders/0_1563294550038.jsonl` |
| **source\_table\_name** | string | The name of the table in the data source.<br><br>**Note**: If this is a subtable created from denesting an array, this value will be the array key. For example: If `orders.order_items`, this value would be `order_items`. |

### Bookmark metadata object properties

If the table uses [Key-based](https://help.qlik.com/en-US/stitch/replication/replication-methods/key-based-incremental) or [Log-based Incremental Replication](https://help.qlik.com/en-US/stitch/replication/replication-methods/log-based-incremental), the `bookmark_metadata` array will contain info about the table’s Replication Key.

A `bookmark_metadata` object contains the following properties:

| **Attribute name** | **Type** | **Description** |
| --- | --- | --- |
| **key** | string | The name of the column the table uses as a [Replication Key](https://help.qlik.com/en-US/stitch/replication/replication-keys). |
| **min\_value** | string | The minimum value of the Replication Key column that was extracted. |
| **max\_value** | string | The maximum value of the Replication Key column that was extracted. Stitch will use this value during the next replication job to identify new and updated data. |