Skip to main content

Webhooks

Apps send automated messages, known as webhooks, when a change occurs.

Our implementation does not require constant data monitoring. Using a field boundary as an example, a CNH webhook will have a trigger in place that only sends a message when there is a specified change in said boundary.

Endpoints
View All
This is a list of featured endpoints. The entries below link to Swagger documentation.

Managing Webhook Subscriptions

In the Developer Portal, users can add, update or disable Webhook Subscriptions.

  • Adding a Subscription

    1. Select webhooks page from the side navigation menu.
    2. At the top of the table, select Add New Subscription.
    3. Ensure the toggle button in the top right corner is selected on Production or Stage as is appropriate. Each single clientId can have its own subscription for EventType.
  • Updating a Subscription

    1. Select webhooks page from the side navigation menu.
    2. Select the subscription name on the Subscription page list.
      • While updating, the “Application Client Id” and “Event Type” fields will be uneditable.
  • Enable or Disable Subscription

    1. Select webhooks page from the side navigation menu.
    2. Find your subscription in the table.
    3. Toggle the switch for that particular subscription.

The table below descibes fields used when adding or editing a webhook subscription.

Field NameComments
Event TypeDescribes which type of event this subscription was created for.

Available values include: Grower, Farm, FarmField, FieldBoundary, Task, Operation, and File.
Subscription NameThe name of the subscription.
Application Client IdThe FMIS Partner application client ID
TokenUsed to validate whether the webhook request is coming from a valid Event-Grid topic.

It is a custom token provided by the FMIS partner while creating the webhook subscription. It allows the FMIS partner to validate on this end if a webhook request is coming from an expected subscription or not. This token will be passed in every webhook request, in the request body.
Target EndpointShould be a valid application URL, which is where data will be posted. The only supported protocol is HTTPS. It will be invoked using the POST method, with the body being set to payload based on the EventType.

On creation of a new subscription, event grid will send a one time validation request to the Target Endpoint, this validation request contains the Validation Code.

A webhook should handle subscription events and respond with 200 HTTP code and the same Validation Code received in the validation request. This is to ensure that Target EndPoint is indeed a valid and working URL.

It is important to verify that the target endpoint URL is able to handle the validation request sent from the event grid before a subscription is created for any event type.

A Validation Request is sent only one time while creating or updating a subscription. If the validation request fails for any reason, the new subscription will not be created and the user will be notified onscreen.

Example

A sample validation payload is available below, along with a C# webhook implementation to handle the validation request.

Payload

[
{
"id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66",
"topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"subject": "",
"data": {
"validationCode": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6",
"validationUrl": "https://rp-eastus2.eventgrid.azure.net:553/eventsubscriptions/myeventsub/validate?id=0000000000-0000-0000-0000-00000000000000&t=2021-09-01T20:30:54.4538837Z&apiVersion=2018-05-01-preview&token=1A1A1A1A"
},
"eventType": "Microsoft.EventGrid.SubscriptionValidationEvent",
"eventTime": "2021-00-01T22:12:19.4556811Z",
"metadataVersion": "1",
"dataVersion": "1"
}
]

Implementation

// HttpPost
public IActionResult InitializeAction([FromBody] List<SubscriptionValidationEventModel> subscriptionValidationEvents)
{
try
{
SubscriptionValidationResponseModel responseModel = new SubscriptionValidationResponseModel
{
ValidationResponse = subscriptionValidationEvents.FirstOrDefault().Data.ValidationCode
};

if (subscriptionValidationEvents.FirstOrDefault().EventType == "Operation")
{
// Implement your business logic here
}
if (subscriptionValidationEvents.FirstOrDefault().EventType == "FieldBoundary")
{
// Implement your business logic here
}
if (subscriptionValidationEvents.FirstOrDefault().EventType == "Grower")
{
// Implement your business logic here
}
if (subscriptionValidationEvents.FirstOrDefault().EventType == "File")
{
// Implement your business logic here
}
if (subscriptionValidationEvents.FirstOrDefault().EventType == "Task")
{
// Implement your business logic here
}
if (subscriptionValidationEvents.FirstOrDefault().EventType == "FarmField")
{
// Implement your business logic here
}
if (subscriptionValidationEvents.FirstOrDefault().EventType == "Farm")
{
// Implement your business logic here
}

return Ok(responseModel);
}
catch (Exception ex)
{
throw ex;
}
}

Webhook Broadcast Payload Message Format

The table below contains descriptions of the different properties appearing in a webhook broadcast payload.

PropertyDescription
eventTypeDescribes what type of event this subscription has been created for.

Available values are Grower, Farm, FarmField, FieldBoundary, Task, Operation, and File.
tokenToken are used to validate whether webhook request is coming from valid Event-Grid topic.

It is a custom token provided by FMIS partner while creating webhook subscription to allow FMIS partner to validate at their end if a webhook request is coming from expected subscription or not. This token will be passed in every webhook request in request body.
targetResourceFMIS API path which can be used for GET request data.
subjectNotification subject.
subscriptionIdSubscription-unique database identification.
messageIdLarge message chunk identification.
dataEntity Information in JSON format. It will be based on event type.

Examples

Below are examples of the message format used for each event types.

Grower

{
"eventType": "Grower",
"token": "TXXXXC0",
"targetResource": "/companies/{companyId}/growers",
"subject": "CNH Event Notification",
"subscriptionId": "xxxxxx-fea3-4a0e-a52d-xxxxxxxx",
"messageGroupId": "xxxxxx-b330-4baa-8942-xxxxxxxxx",
"data": {
"companyId": "ACC0XXXXX55",
"action": "upsert",
"growers": [
{
"growerId": "xxxxxxx-7f5c-xxx-xxx-xxxxxxx"
},
{
"growerId": "xxxxxxx-9820-xxx-xxx-xxxxxxx"
}
]
}
}

Farm

{
"eventType": "Farm",
"token": "TXXXXC0",
"targetResource": "/companies/{companyId}/growers/{growerId}/farms",
"subject": "CNH Event Notification",
"subscriptionId": "xxxxxx-fea3-4a0e-a52d-xxxxxxxx",
"messageGroupId": "xxxxxx-b330-4baa-8942-xxxxxxxxx",
"data": {
"growerId": "xxxxxx-bf86-xxxx-b8fa-xxxxxxxxx",
"companyId": "ACC0XXXXX55",
"action": "upsert",
"farms": [
{
"farmId": "xxxxxxx-7f5c-xxx-xxx-xxxxxxx"
},
{
"farmId": "xxxxxxx-9820-xxx-xxx-xxxxxxx"
}
]
}
}

FarmField

{
"eventType": "FarmField",
"token": "TXXXXC0",
"targetResource": "/companies/{companyId}/farms/{farmId}}/fields",
"subject": "CNH Event Notification",
"subscriptionId": "xxxxxx-fea3-4a0e-a52d-xxxxxxxx",
"messageGroupId": "xxxxxx-b330-4baa-8942-xxxxxxxxx",
"data": {
"farmId": "xxxxxx-bf86-xxxx-b8fa-xxxxxxxxx",
"companyId": "ACC0XXXXX55",
"action": "upsert",
"fields": [
{
"fieldId": "xxxxxxx-7f5c-xxx-xxx-xxxxxxx"
},
{
"fieldId": "xxxxxxx-9820-xxx-xxx-xxxxxxx"
}
]
}
}

FieldBoundary

{
"eventType": "FieldBoundary",
"token": "TXXXXC0",
"targetResource": "/companies/{companyId}/fields/{fieldId}/fieldsetupdata/boundaries",
"subject": "CNH Event Notification",
"subscriptionId": "xxxxxx-fea3-4a0e-a52d-xxxxxxxx",
"messageGroupId": "xxxxxx-b330-4baa-8942-xxxxxxxxx",
"data": {
"fieldId": "xxxxxx-bf86-xxxx-b8fa-xxxxxxxxx",
"companyId": "ACC0XXXXX55",
"action": "upsert",
"boundaries": [
{
"boundaryId": "xxxxxxx-7f5c-xxx-xxx-xxxxxxx",
"operation": "update"
},
{
"boundaryId": "xxxxxxx-9820-xxx-xxx-xxxxxxx",
"operation": "update"
}
]
}
}

Operation

{
"eventType": "Operation",
"token": "TXXXXC0",
"targetResource": "/companies/{companyId}/fields/{fieldId}/operations",
"subject": "CNH Event Notification",
"subscriptionId": "xxxxxx-fea3-4a0e-a52d-xxxxxxxx",
"messageGroupId": "xxxxxx-b330-4baa-8942-xxxxxxxxx",
"data": {
"companyId": "ACC0XXXXX55",
"action": "upsert",
"fieldOperations": [
{
"fieldId": "xxxxxxx-7f5c-xxx-xxx-xxxxxxx",
"operations": [
{
"operationId": "XXXXXXXXX-a168-XXXX-bcd8-XXXXXXXXXXX"
},
{
"operationId": "XXXXXXXXX-f191-XXXX-8cf1-XXXXXXXXXXX"
}
]
}
]
}
}

Task

{
"eventType": "Task",
"token": "TXXXXC0",
"targetResource": "/companies/{companyId}/fields/{fieldId}/tasks",
"subject": "CNH Event Notification",
"subscriptionId": "xxxxxx-fea3-4a0e-a52d-xxxxxxxx",
"messageGroupId": "xxxxxx-b330-4baa-8942-xxxxxxxxx",
"data": {
"companyId": "ACC0XXXXX55",
"action": "upsert",
"fieldTasks": [
{
"fieldId": "xxxxxxx-7f5c-xxx-xxx-xxxxxxx",
"tasks": [
{
"taskId": "XXXXXXX-XXXXX-49aa-XXXX-XXXXXXXX"
}
]
}
]
}
}

API Environments

When developing an application, you rarely want to make changes and perform testing in a live environment, particularly after you've shipped your product and have a steady user base.

To that end, CNH provides two environment contexts for its API:

  • Staging
  • Production

The environments are identical, requiring only that you change out your connection string and authorization endpoint to connect to either.

EnvironmentBase URL
Staginghttps://stg.api.cnhind.com/mkt/fmis/v2
Productionhttps://ag.api.cnhind.com/v2
It is highly recommended to abstract away the connection strings from your code to allow you to easily swap between environments with your application.

Webhook Postman Collection

Under construction.