> For the complete documentation index, see [llms.txt](https://docs.agilecase.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.agilecase.com/developer-documentation/webhooks/incoming-webhooks.md).

# Incoming Webhooks

## Overview

The Incoming Webhooks feature allows a user to configure any third party system which can send a JSON webhook (for example TypeForm, JotForm, Google Forms) to save form information directly to AgileCase.

An incoming webhook can either create a new case or update an existing one, and it can populate contacts, case fields, custom fields and table rows along the way. What it does is controlled entirely by a JSON mapping file that you write and upload, so no code is involved.

{% stepper %}
{% step %}

### Request a SeedGUID

A secure key for your account (called a **SeedGUID**) is required. Put this in your mapping file and URL to ensure only you can configure a webhook for your account.

You can request your SeedGUID from AgileCase Support when you are ready to use the Incoming Webhook feature.
{% endstep %}

{% step %}

### Create a mapping file

Create a mapping file in JSON format which describes how to map the "source fields" from your webhook to the "destination fields" within AgileCase.

Although it looks quite technical, the mapping file is actually very simple once the contents are understood.
{% endstep %}

{% step %}

### Upload and use the mapping file

Upload the Mapping File just like a Document Template, then use the ID of the uploaded JSON Template in the URL for your webhook.

`https://<your-provided-endpoint>.agilecase.com/webhooks-uploader/<json_template_id>`

A legacy URL format, which is still valid, is:

`https://<your-provided-endpoint>.agilecase.com/webhooks-uploader/generic_uploader/update?documentId=<your_mapping_file_id>&key=<your_key>`
{% endstep %}
{% endstepper %}

Please contact support to have Webhooks configured on your account and given your unique endpoint and api key.

## Mapping File Contents

The mapping file is formatted in JSON and describes how to map the data sent to the webhook into AgileCase. You can see an example of a JSON mapping file attached below.

At a high level, a JSON file is simply a set of labels and values stored like this:

```json
{"label":"value"}
```

The Labels are largely fixed, while the values can be changed to what you need to achieve your mappings. Typically you will only ever change the value part and sometimes add in additional parts if you need to map more than one field.

Every line is separated from the next by a comma and sometimes you may see groups of these labels and values surrounded by square brackets (i.e. `[ ]`) which denotes there are multiple of the same label.

All "mappings" to the source data use a format called "JSONPath". JSONPath allows for very complex expressions to extract data from your source data but at its simplest form it is simply the "address" of the data you want to find, separated by dots.

For example, given a source file like:

```json
{
   "source_data": {
      "first_parent": {
         "second_parent": {
            "child_data_i_want": "value"
         }
      }
   }
}
```

The JSONPath to get the child data would be: `source_data.first_parent.second_parent.child_data_i_want`.

You can find more guides on more complex JSONPath online (should you ever need to handle arrays or include only some elements based on their value, etc.) and a useful tool to test your JSONPath is correct at: [https://jsonpath.curiousconcept.com](https://jsonpath.curiousconcept.com/)

We will break down the file here so it's easy to understand and make the changes you require for your own mapping.

### 1. Top Level Mapping Instructions

At the beginning of the file there are some standard field labels, their meaning and what you should set the value to be.

```json
{
    "ActionMethod": 1,
    "SeedGUID": "<Security Key>",
    "downloadFileURLSuffix": "<required for some 3rd party services to download attached files>",
    "PracticeID": 1234,
    "PartnerID": 5678,
    "FeeEarnedID": [1234],
    "CaseTypeID": 5678,
    "ClientID": 1234,
    "SourceID": 5678,
    "DuplicateCheck": ["ClientReference"],
    "FindCaseBy": "CaseNumberAndId",
    "CaseNumber_externalKey": "<JSONPath expression>",
    "CaseID_externalKey": "<JSONPath expression>"
}
```

* `ActionMethod` - This field determines if you wish to Create a new Case from this Webhook (`1`), or to Update an existing Case (`2`). The values here must always be `1` or `2`.
* `SeedGUID` - This will be a long string which is unique to your account. Support will provide this and it is important you do not share this string with anyone else.
* `downloadFileURLSuffix` - If your 3rd party service requires any form of additional parameter to download files submitted via the Webhook then please provide it here. For example for JotForm an additional URL parameter named "apiKey" is required and you would provide that here as `"apikey=<your_jotform_apikey>"`.
* `PracticeID` - The practice ID of the Case you wish to work with - you should provide this both for Creating new Cases and Updating existing Cases.
* `PartnerID` - The user ID of the user you wish to set as the partner of a Case.
* `FeeEarnedID` - An array of user IDs who may be assigned as Fee Earners of the Case. If more than 1 user ID is provided then the case will be randomly assigned to a single user in the list.
* `CaseTypeID` - The CaseTypeID for the case. Required for ActionMethod 1 (Create). Also required for ActionMethod 2 (Update) when FindCaseBy is set to `"CaseNumberAndCaseType"`.
* `ClientID` - This can be statically mapped here by providing a number, or if you provide a string it can source ClientID from the source data. It is also possible to simply provide “ClientID” in the source data without having a specific mapping. You should only supply a mapping for “ClientID” if the client is already existing within your system and not being created as a Contact dynamically.
* `SourceID` - The SourceID for a Create Case, ignored for ActionMethod 2.
* `DuplicateCheck` - An optional array of field names used to prevent duplicate cases being created. For example, `["ClientReference"]` will check if a case with the same client reference already exists before creating a new one. Used with ActionMethod 1.
* `FindCaseBy` - The method for "finding" the case to be updated when ActionMethod is 2. Supported values are:
  * `"CaseNumberAndId"` - Finds the case by matching both the Case Number and Case ID. Requires `CaseNumber_externalKey` and `CaseID_externalKey` to be set.
  * `"CaseNumberAndCaseType"` - Finds the case by matching the Case Number and Case Type. Requires `CaseNumber_externalKey`, `CaseID_externalKey` and `CaseTypeID` to be set.
* `CaseNumber_externalKey` - The JSONPath expression to the Case Number in the incoming JSON data.
* `CaseID_externalKey` - The JSONPath expression to the Case ID in the incoming JSON data.

### 2. Contact Data Mapping

Each entry in the `ContactData` array maps to a single contact in AgileCase. When creating a Case the Contact is also created by default.

```json
"ContactData": [
    {
        "RelationshipName": "Client",
        "IsClient_externalKey": "<JSONPath expression>",
        "Firstname_externalKey": "<JSONPath expression>",
        "Lastname_externalKey": "<JSONPath expression>",
        "DateOfBirth_externalKey": "<JSONPath expression>",
        "EmailAddress_externalKey": "<JSONPath expression>",
        "Phone_externalKey": "<JSONPath expression>",
        "Street_externalKey": "<JSONPath expression>",
        "emailHandling": "skip_duplicate_check",
        "CustomFieldMapping": [
            {
                "externalKey": "<JSONPath expression>",
                "customfieldid": 1234,
                "mapping_description": "Describe your mapping here"
            }
        ]
    },
    {
        "RelationshipName": "Borrower1",
        "Firstname_externalKey": "<JSONPath expression>",
        "Lastname_externalKey": "<JSONPath expression>",
        "Street_externalKey": "<JSONPath expression>"
    }
]
```

You can define multiple contacts by adding additional entries to the `ContactData` array, each with a different `RelationshipName` (e.g. "Client", "Borrower1", "Borrower2").

{% hint style="info" %}
Adding a “Client” contact is mandatory if you are not providing ClientID in the mapping file or source data.
{% endhint %}

You can also decide if any contact created is marked as a Client. To do this, add `"IsClient_externalKey": "your_column_name"` to any `ContactData` block in a mapping file to match incoming data format. Accepted truthy values in the data: `true`, `1`, `yes` (case-insensitive).

#### Supported Contact Fields

| Field                      | Description                                                                                             |
| -------------------------- | ------------------------------------------------------------------------------------------------------- |
| `RelationshipName`         | The relationship of the contact to the case (e.g. "Client", "Borrower1", "Borrower2")                   |
| `IsClient`                 | JSONPath to ‘truthy’ value (e.g. true, 1, yes)                                                          |
| `Firstname_externalKey`    | JSONPath to the contact's first name                                                                    |
| `Lastname_externalKey`     | JSONPath to the contact's last name                                                                     |
| `DateOfBirth_externalKey`  | JSONPath to the contact's date of birth                                                                 |
| `Gender_externalKey`       | JSONPath to the contact's gender                                                                        |
| `EmailAddress_externalKey` | JSONPath to the contact's email address                                                                 |
| `Phone_externalKey`        | JSONPath to the contact's phone number                                                                  |
| `Street_externalKey`       | JSONPath to address line 1                                                                              |
| `Street2_externalKey`      | JSONPath to address line 2                                                                              |
| `City_externalKey`         | JSONPath to the city                                                                                    |
| `State_externalKey`        | JSONPath to the state/county                                                                            |
| `Zip_externalKey`          | JSONPath to the postcode/zip                                                                            |
| `Country_externalKey`      | JSONPath to the country                                                                                 |
| `emailHandling`            | Optional. Set to `"skip_duplicate_check"` to bypass duplicate email checking when creating this contact |

{% hint style="info" %}
Only the default/home Email, Phone and Address will be created/updated via the Webhook feature at this time.
{% endhint %}

Each contact can also include a `CustomFieldMapping` array to map source data to custom fields on the contact, using the same structure described above.

### 3. Case Data Fields

Case data allows for Description, Client Reference and Custom Fields to be mapped.

```json
"CaseData": {
    "Description_externalKey": "<JSONPath expression or literal value>",
    "ClientReference_externalKey": "<JSONPath expression>",
    "CustomFieldMapping": [
        {
            "externalKey": "<JSONPath expression>",
            "customfieldid": 1234,
            "mapping_description": "Description of this mapping"
        }
    ]
}
```

* `Description_externalKey` - The JSONPath expression (or a literal value) to set as the Case Description.
* `ClientReference_externalKey` - The JSONPath expression to the Client Reference Number in the source data. This is used to set the Client Reference on the case and is also used by the `DuplicateCheck` feature when checking for existing cases.
* `CustomFieldMapping` - An array of mappings from source data fields to AgileCase custom fields on the case. Each entry requires:
  * `externalKey` - The JSONPath expression to the source data value
  * `customfieldid` - The AgileCase Custom Field ID to store the value in
  * `mapping_description` - A human-readable note describing the mapping (for your own reference only)

### 4. Case Table Data

You can map table data using the following structure. You include the Group ID of the Table you want to create in the `CustomFieldGroupID` field. Only adding new Table rows is supported at this time.

```json
"CaseTableData": {
    "mapping_description": "Description for the note created with the table row",
    "CustomFieldGroupID": 1176,
    "CustomFieldMapping": [
        {
            "externalKey": "formTitle",
            "customfieldid": 3045,
            "mapping_description": "table group - text box"
        },
        {
            "externalKey": "rawRequest.q24_fieldname",
            "customfieldid": 3044,
            "mapping_description": "table group - text area"
        },
        {
            "externalKey": "rawRequest.q31_datefield",
            "customfieldid": 3044,
            "mapping_description": "table group - date box"
        },
        {
            "externalKey": "rawRequest.fileuploadfield",
            "customfieldid": 3044,
            "mapping_description": "table group - file upload control"
        }
    ]
}
```

### 5. Testing Access

We recommend all customers test their mapping file first in a test environment. Please contact support to request access to our testing servers which will allow you to check your work before putting it live.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.agilecase.com/developer-documentation/webhooks/incoming-webhooks.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
