Webhooks

For easy data push integration between Netilion and your application, Netilion offers webhooks. When configured, a webhook is used to send out notifications to your service. Once you have configured a URL, Netilion will post the event data as JSON to your webhook URL. You can subscribe to different event types. Please see the API documentation for all supported types.

When to use webhooks

When your application needs to get informed automatically about changes and new data in Netilion, you can use webhooks. With webhooks you do not need to poll for new data. Webhooks are posted asynchronously.

Prerequisites

To receive webhooks, you need an active Netilion Connect subscription with at least one API key. Calls and payload size will be added to the quota usage of the Connect subscription. If the quota exceeds, the corresponding webhooks will not be called.

Permissions

Webhooks get events for objects they have read permissions by the technical users of the Netilion Connect subscription.

Handling Webhooks

The provided URL must be a public accessible https address that handles HTTP POST requests.

Netilion needs to get a status code 2XX reply from the configured URL to confirm that the notification sent via HTTP POST has been successfully delivered. If any webhook times out or another status code was returned, Netilion will retry multiple times to deliver the event data.

Configure Webhooks

To register a webhook, the ID of the Client Application is needed. With every Netilion Connect subscription a client application is generated. If you do not already have the ID, you can find it via API GET https://api.netilion.endress.com/v1/client_applications?name=YOURDEFINEDNAME

With this ID you can register your Webhook (via POST https://api.netilion.endress.com/v1/client_applications/ID/webhooks, see API documentation for rerquest body) and will get the secret in the response. The secret is needed for validating the payload.

Validating payloads

Clients using the webhooks should ensure that requests come from Netilion. With each incoming POST request from Netilion, a hash signature will be passed in the headers. Following signatures are available:

HMAC SHA-1 (deprecated, may be removed in future):

Header name: X-Hub-Signature

Value: sha1=XYZ

HMAC SHA-256:

Header name: X-Hub-Signature-Sha256

Value: sha256=XYZ

These signatures can be used to validate the source of the data is Netilion. The hash signature starts with the used hash e.g. sha256=, indicating the use of HMAC SHA-256 to encrypt. The secret used to create the signatures is generated automatically when a new webhook is created and returned in the API call. It can be changed with the change secret endpoint. To calculate the signature, use the provided secret as key and the received payload as data

Steps to validate a request

  • Create a hash using your secret and incoming payload body.
  • Compare created hash with the signature value provided in the header.

Example code for validation:

class NetilionController < ApplicationController

  def process
    raise AuthenticationFailed if request.headers['X-Hub-Signature-Sha256'].blank?
    calculated_signature = "sha256=#{OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), ENV['webhook_secret'], request.raw_post)}"
    raise AuthenticationFailed unless Rack::Utils.secure_compare(calculated_signature, request.headers['X-Hub-Signature'])

    event = JSON.parse(request.body.string)
    .....
  end

end

Payload & Event Types

The payload of the webhook contains the event_type and the content, which is different depending on the event type.

Currently, following event types are supported:

asset_value_created

Will be sent, when a new asset value gets created. Each value will be sent separately in a webhook call. The payload of this event looks like the following:

{
  "event_type": "asset_value_created",
  "occurred_at": "2020-03-04T09:15:00",
  "content": {
    "asset": {
      "id": 4079332,
      "href": "https://api.netilion.endress.com/v1/assets/4079332"
    },
    "value": {
      "key": "level",
      "group": "measurement",
      "unit": {
          "id": 8594,
          "href": "https://api.netilion.endress.com/v1/units/8594"
      },
      "timestamp": "2020-03-04T08:38:25Z",
      "value": "96.45"
    }
  }
}

asset_values_created

Is sent whenever new asset values are sent to the hub. Use this webhook if the asset sends several values at once, and you prefer to recieve them all in one webhook. This webhook sends multiple values grouped under their keys as shown in this example.

Optionally you can define the value keys that should be send:

Example request format to get only values with the key pressure or value

{
  "url": "https://my.super.app/netiliondata",
  "event_types": [
    "asset_values_created"
  ],
  "properties": {
    "asset_values_created": [
      "pressure", "level"
    ]
  }
}
{
  "event_type": "asset_values_created",
  "occurred_at": "2020-03-04T09:15:00",
  "content": {
    "asset": {
      "id": 4079332,
      "href": "https://api.netilion.endress.com/v1/assets/4079332"
    },
    "values": [
      {
        "key": "volumeflow",
        "group": "measurement",
        "unit": {
          "id": 8594,
          "href": "https://api.netilion.endress.com/v1/units/8594"
        },
        "data": [
          {
            "timestamp": "2020-03-04T08:38:25Z",
            "value": "88.99"
          },
          {
            "timestamp": "2020-03-04T08:38:25Z",
            "value": "90.00"
          }
        ]
      }, {
        "key": "pressure",
        "group": 'measurement',
        "unit": {
          "id": 222,
          "href": "https://api.netilion.endress.com/v1/units/222"
        },
        "data": [
          {
            "timestamp": "2020-03-04T08:38:25Z",
            "value": "88.99"
          },
          {
            "timestamp": "2020-03-04T08:38:25Z",
            "value": "90.00"
          }
        ]
      }
    ]
  }
}

instrumentation_values_created

Is sent whenever new values of an asset with an instrumentation are sent to the hub. Use can register to this webhook to receive the values for single values or if several values are send at once. This webhook sends multiple values grouped under their keys if as shown in this example, if the values were created with one request.

Optionally you can define the value keys that should be send:

Example request format to get only values with the key pressure or value

{
  "url": "https://my.super.app/netiliondata",
  "event_types": [
    "instrumentation_values_created"
  ],
  "properties": {
    "instrumentation_values_created": [
      "pressure", "level"
    ]
  }
}
{
  "event_type": "instrumentation_values_created",
  "occurred_at": "2020-03-04T09:15:00",
  "content": {
    "instrumentation": {
      "id": 4079332,
      "href": "https://api.staging-env.netilion.endress.com/v1/instrumentations/4079332"
    },
    "values": [
      {
        "key": "level",
        "group": "measurement",
        "unit": {
            "id": 8594,
            "href": "https://api.staging-env.netilion.endress.com/v1/units/8594"
        },
        "data": [
          {
            "timestamp": "2020-03-04T08:38:25Z",
            "value": 96.45
          },
          {
            "timestamp": "2020-03-04T09:00:00Z",
            "value": 100.00
          }
        ]
      },
      {
        "key": "temperature",
        "group": "measurement",
        "unit": {
          "id": 123,
          "href": "https://api.staging-env.netilion.endress.com/v1/units/123"
        },
        "data": [
          {
            "timestamp": "2020-03-04T09:00:00Z",
            "value": 19.5
          }
        ] 
      }
    ]
  }
}

asset_updated

Is sent when parameters of an asset get updated. When creating a webhook, add the asset attributes which value updates that you prefer to get notified of.

Example request format to get events when the status or the description of an asset has changed

{
  "url": "https://my.super.app/netiliondata",
  "event_types": [
    "asset_updated"
  ],
  "properties": {
    "asset_updated": [
      "status", "description"
    ]
  }
}

For asset_updated event type below attributes are supported.

  • serial_number, description, production_date, last_seen_at, product, parent, tenant, status

If a user doesn't add any attribute specifically when registering to the webhook, changes of the all above-mentioned attributes will use for notification

Example Payload (if the status has changed):

{
   "event_type": "asset_updated",
   "occurred_at": "2021-03-03T19:20:30+01:00",
   "content": {
       "asset": {
        "id": 67237,
        "href": "https://api.netilion.endress.com/v1/assets/67237"
        "status": {
          "id": 42,
          "href": "https://api.netilion.endress.com/v1/asset/status/42"
        }
       }
    }
}

asset_software_added

Is sent whenever a new software is assigned to an asset.

Payload Example:

{
  "event_type": "asset_software_added", 
   "occurred_at": "2020-03-04T09:15:00",
  "content": {
    "asset": {
      "id": 4079332,
      "href": "https://api.netilion.endress.com/v1/assets/4079332"
    },
    "software": {
      "id": 123456,
      "href": "https://api.netilion.endress.com/v1/softwares/123456"
    }
  }
}

asset_instrumentation_association_created

Is sent whenever a new association between asset and instrumentation is created.

Payload Example:

{
  "event_type": "asset_instrumentation_association_created",
  "occured_at": "2021-03-03T19:20:30+01:00",
  "content": {
    "asset": {
      "id": 4079332,
      "href": "https://api.netilion.endress.com/v1/assets/4079332"
    },
    "instrumentation": {
      "id": 123456,
      "href": "https://api.netilion.endress.com/v1/instrumentations/123456"
    }
  }
}

asset_instrumentation_association_destroyed

Is sent whenever a association between asset and instrumentation is destroyed.

Payload Example:

{
  "event_type": "asset_instrumentation_association_destroyed",
  "occured_at": "2021-03-03T19:20:30+01:00",
  "content": {
    "asset": {
      "id": 4079332,
      "href": "https://api.netilion.endress.com/v1/assets/4079332"
    },
    "instrumentation": {
      "id": 123456,
      "href": "https://api.netilion.endress.com/v1/instrumentations/123456"
    }
  }
}

instrumentation_appeared

Is sent whenever a technical user gets read permission on an instrumentation.

Payload Example:

{
  "event_type": "instrumentation_appeared",
  "occurred_at": "2020-03-04T09:15:00",
  "content": {
    "instrumentation": {
      "id": 4079332,
      "href": "https://api.netilion.endress.com/v1/instrumentations/4079332"
    },
    "user": {
      "id": 123456,
      "href": "https://api.netilion.endress.com/v1/users/123456"
    }
  }
}

instrumentation_disappeared

Is sent whenever a technical user lost it's read permission on an instrumentation.

Payload Example:

{
  "event_type": "instrumentation_disappeared",
  "occurred_at": "2020-03-04T09:15:00",
  "content": {
    "instrumentation": {
      "id": 4079332,
      "href": "https://api.netilion.endress.com/v1/instrumentations/4079332"
    },
    "user": {
      "id": 123456,
      "href": "https://api.netilion.endress.com/v1/users/123456"
    }
  }
}

asset_specifications_updated

Is sent if one or more specifications of an asset get updated, one event is sent per request per webhook, regardless how many keys were changed in the request. If you want to limit it to a set of keys, you can add the asset_specifications_updated property with the list of keys which value updates are of interest for notification.

Example request format to get events when the specification my_key1, my_key2, my_key3 of an asset has changed

{
  "url": "https://my.super.app/netiliondata",
  "event_types": [
    "asset_specifications_updated"
  ],
  "properties": {
    "asset_specifications_updated": [
      "my_key1", "my_key2", "my_key3"
    ]
  }
}

If a user doesn't add any attribute when registering to the webhook, changes of any of the specifications will be notified.

Example Payload (if only specifications my_key2, my_key_3 have changed within the request):

{
  "event_type": "asset_specifications_updated",
   "occurred_at": "2021-03-03T19:20:30+01:00",
  "content": {
    "asset": {
      "id":23,
        "href":"https://api.netilion.endress.com/v1/assets/23"
      "specifications":
      {
        "my_key2": {
          "unit": null, "value": "new_value2", "updated_at": "2021-05-26T12:38:37.743Z", "source_timestamp": null
        },
        "my_key3": {
          "unit": null, "value": "new_value3", "updated_at": "2021-05-26T12:38:37.697Z", "source_timestamp": null
        }
      }
    }
  }
}

event_specifications_updated

Is sent if one or more specifications of an event get updated, one event is sent per request per webhook, regardless how many keys were changed in the request. If you want to limit it to a set of keys, you can add the event_specifications_updated property with the list of keys which value updates are of interest for notification.

Example request format to get events when the specification my_key1, my_key2, my_key3 of an event has changed

{
  "url": "https://my.super.app/netiliondata",
  "event_types": [
    "event_specifications_updated"
  ],
  "properties": {
    "event_specifications_updated": [
      "my_key1", "my_key2", "my_key3"
    ]
  }
}

If a user doesn't add any attribute when registering to the webhook, changes of any of the specifications will be notified.

Example Payload (if only specifications my_key2, my_key_3 have changed within the request):

{
  "event_type": "event_specifications_updated",
   "occurred_at": "2021-03-03T19:20:30+01:00",
  "content": {
    "event": {
      "id":23,
        "href":"https://api.netilion.endress.com/v1/events/67237"
      "specifications":
      {
        "my_key2": {
          "unit": null, "value": "new_value2", "updated_at": "2021-05-26T12:38:37.743Z", "source_timestamp": null
        },
        "my_key3": {
          "unit": null, "value": "new_value3", "updated_at": "2021-05-26T12:38:37.697Z", "source_timestamp": null
        }
      }
    }
  }
}

event_created

Is sent if an event in Netilion is created (not to confuse with the webhook event, for more information check: https://api.netilion.endress.com/doc/v1#/Event ), one webhook event is sent per request per webhook. If you want to limit it to a set of event types, you can add the event_created property with the list of event type codes which new events are of interest for notification. In order to get event_created events, the technical user of the client application should have at least read permissions on one of the assets or instrumentations given in the POST call of the events request.

Example request format to get webhook events when events with type codes heartbeat_verification or device_certificate_renewal are created:

{
  "url": "https://my.super.app/netiliondata",
  "event_types": [
    "event_created"
  ],
  "properties": {
    "event_created": [
      "heartbeat_verification", "device_certificate_renewal"
    ]
  }
}

If a user doesn't add any attribute when registering to the webhook, any event creation process will be notified.

Example Payload:

{
    "event_type": "event_created",
    "occurred_at": "2021-03-03T19:20:30+01:00",
    "content": {
        "event": {
            "id": 11,
            "href": "https://api.netilion.endress.com/v1/events/11",
            "name": "ntestKais",
            "responsible": 'Hans',
            "type": {
                "id": 2,
                "code": "device_certificate_renewal",
                "href": "https://api.netilion.endress.com/v1/event/types/2"
            },
            "status": {
                "id": 1,
                 "code": "scheduled",
                 "href": "https://api.netilion.endress.com/v1/event/statuses/1"
            },
            "assets": [
                {
                    "id": 1,
                    "href": "https://api.netilion.endress.com/v1/assets/1"
                },
                {
                    "id": 2,
                    "href": "https://api.netilion.endress.com/v1/assets/2"
                }
            ],
            "instrumentations": [
                {
                    "id": 1,
                    "href": "https://api.netilion.endress.com/v1/instrumentations/1"
                }
            ],
            "documents": [
                {
                    "id": 3,
                    "href": "https://api.netilion.endress.com/v1/documents/3"
                }
            ]
        }
    }
}

event_document_created

Is sent whenever a document is assigned to an event.

similar to the webhook event_created, a filter based on the event type code can be given to limit the notification to a certain subset of event type codes. Example request:

{
  "url": "https://my.super.app/netiliondata",
  "event_types": [
    "event_document_created"
  ],
  "properties": {
    "event_document_created": [
      "heartbeat_verification", "device_certificate_renewal"
    ]
  }
}

Payload Example:

{
  "event_type": "event_document_created",
   "occurred_at": "2020-03-04T09:15:00",
  "content": {
    "event": {
      "id": 4079332,
      "href": "https://api.netilion.endress.com/v1/events/4079332"
    },
    "document": {
      "id": 123456,
      "href": "https://api.netilion.endress.com/v1/documents/123456"
    }
  }
}

asset_health_condition_updated

Is sent whenever the health conditions linked to an asset changed

{
  "url": "https://my.super.app/netiliondata",
  "event_types": ["asset_health_condition_updated"]
}

The Webhook payload contains the current status of the asset, the current assigend health conditions and the health conditions assigned before the update

Payload Example:

{
  "event_type": "asset_health_condition_updated",
   "occurred_at": "2020-03-04T09:15:00",
  "content": {
        "asset": {
            "id": 4079332,
                "href": "https://api.netilion.endress.com/v1/assets/4079332"
        },
        "asset_status": {
            "code": "failure",
                "name": "Failure",
                "description": "string",
                "id": 2,
                "tenant": {
                "id": 1,
                 "href": "https://api.netilion.endress.com/v1/tenants/1"
            }
        },
        "health_conditions": [
            {
                "diagnosis_code": "F42",
                "id": 99,
                "asset_status": {
                    "id": 2,
                    "href": "https://api.netilion.endress.com/v1/asset/status/2"
                },
                "channel": "A",
                "module": "B",
                "links": {
                    "causes": {
                        "href": "https://api.netilion.endress.com/v1/health_conditions/99/causes"
                    }
                }
            }
        ], 
        "previous_health_conditions": [
            {
                "diagnosis_code": "M18",
                "id": 1089,
                "asset_status": {
                    "id": 1,
                    "href": "https://api.netilion.endress.com/v1/asset/status/1"
                },
                "channel": "Channel 1",
                "module": "Module 7",
                "links": {
                    "causes": {
                        "href": "https://api.netilion.endress.com/v1/health_conditions/1089/causes"
                    }
                }
            }
        ]
  }
}

product_status_changed

Is sent whenever the product status of a product changed if the user has at least one asset that is linked to the product.

{
  "url": "https://my.super.app/netiliondata",
  "event_types": ["product_status_changed"]
}

The Webhook payload contains the product and status details

Payload Example:

{
    "event_type": "product_status_changed",
        "occurred_at": "2023-03-24T01:00:00+01:00",
        "content": {
          "product": {
            "href": "https://api.netilion.endress.com/v1/products/54",
                "id": 54,
                "product_code": "XYZ",
                "phase_out_date": "2023-03-24",
                "order_stop_date": "2025-01-01",
                "spare_parts_until": "2026-08-04",
                "spare_sensors_until": "2027-09-18",
                "repair_until": "2026-01-01",
                "calibration_until": "2026-03-04",
                "name": "Example Product",
                "status": {
                  "href": "https://api.netilion.endress.com/v1/product/statuses/17",
                  "id": 17,
                  "code": "phase_out",
                  "name": "Phase out",
                  "description": "Order stop dates and successor products have been defined.",
                  "tenant": {
                   "id": 1,
                    "href": "https://api.netilion.endress.com/v1/tenants/1"
                }
            }
        }
    }
}

Retry Handling

As mentioned, Netilion will retry multiple times to deliver the event data if the request was not successful.

Netilion will try to deliver the data 16 times with exponential increasing waiting time between attempts. The waiting time has a randomness, but Netilion will retry to deliver the data for approx. 3 days.

After that, it is possible to manually resend the events to the receiver. Finding the failed events is possible via GET https://api.netilion.endress.com/v1/client_applications/ID/webhooks/webhookID/events?status=failed (more filter options are available, please see API documentation for details). By sending the event IDs to POST https://api.netilion.endress.com/v1/client_applications/ID/webhooks/webhookID/events, Netilion will restart to send the data (with the described retry mechanism). After 6 months, Netilion will remove the data for the failed events and a resending of older events is not possible.

Enable/disable Webhook

Webhook can be disabled or enabled at any time by the user. But there are cases when Netilion disable a webhook on its own e.g. when a webhook events for a certain webhook keep failing for a period longer than two weeks, this will unnecessary uses the connect subscription request quota. The contact person of the client application having this webhook will be notified in such cases, so that the user can recheck the webhook and fix something if needed. To enable/disable a webhook, webhook patch request can be used, e.g in case of enable:

PATCH "https://api.netilion.endress.com/v1/client_applications/{client_application_id}/webhooks/{webhook_id}"
{
  "disabled": false
}