> 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/case-scripting/on-save-scripts/examples/calling-a-webhook-on-a-milestone.md).

# Calling a Webhook on a Milestone

An outgoing webhook lets a case tell another system that something has happened. The usual trigger is a milestone being reached: a date is entered, and an accounts package, portal or scheduling system needs to know without anybody retyping it.

The script's part in this is small. It names a webhook template and the template holds the address, the headers and the body, so the decision the script makes is only whether to send and which event to send.

## The scenario

A charity records that a grant has been awarded. If the case is flagged to post to the finance system, the award is pushed to the accounts package. Restricted funds need a second event to open the restriction.

| Setting       | Value                                                                          |
| ------------- | ------------------------------------------------------------------------------ |
| Trigger field | `5105` Grant awarded (date)                                                    |
| Read          | `5106` Post to finance system (Yes/No), `5107` Fund type                       |
| Webhooks      | `Finance.GrantAwarded`, `Finance.RestrictedFundOpened`, `Finance.CapitalGrant` |

## The script

```javascript
[Changed.CustomField(5105).Changed]

function after_save() {
    if (Changed.CustomField("5105").NewValueAsText === "") {
        return true;
    }

    if (Service.CustomField("5106").ValueAsText != "Yes") {
        return true;
    }

    var fundType = Service.CustomField("5107").ValueAsText;

    Service.SendWebhook("Finance.GrantAwarded");

    if (fundType == "Restricted") {
        Service.SendWebhook("Finance.RestrictedFundOpened");
    } else if (fundType == "Capital") {
        Service.SendWebhook("Finance.CapitalGrant");
    }

    Service.AddMessage("The finance system has been notified of this award.", "notify-success");
    return true;
}
```

## Only after\_save

There is no `on_save` in this script at all, which is allowed: the save goes ahead and the work happens once the values are stored.

For a webhook this is the right choice rather than a convenience. The receiving system will usually read the case back, or trust the values in the body, and either way it should be told about data that has actually been committed. Sending from `on_save` would announce a state the case had not yet reached, and if anything then stopped the save you would have told another system about something that never happened.

## The gate before the send

Both early returns exist because a webhook cannot be recalled. Clearing the award date is a change and would otherwise announce an award that had just been removed, and the flag on `5106` lets a case be worked without pushing anything, which matters while a case is being set up or corrected.

Checking `!= "Yes"` rather than `== "No"` means an unanswered flag also sends nothing. With an integration, defaulting to not sending is the safer way round.

The first webhook is sent unconditionally once the gate is passed, and the fund type only decides whether a second, more specific event follows. Keeping the general event separate from the specialised one means the receiving system always gets the award, whatever fund types you add later.

{% hint style="warning" %}
A failed webhook is recorded against the case but is not retried, and the person who saved the case is not told. A missing endpoint or an expired credential will therefore look like a success from inside AgileCase. Check the case's communications if another system appears not to have received something.
{% endhint %}

## Setting up the template

The script only names the template; everything else is configured alongside your SMS templates, because a webhook is an SMS template whose recipient is an HTTP address rather than a phone number. The address can carry headers for authentication, and the body is built from merge fields in the same way as an email.

Setting that up, including the header syntax and what a receiving system sees, is covered in [Outgoing Webhooks](/developer-documentation/webhooks/outgoing-webhooks.md).


---

# 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/case-scripting/on-save-scripts/examples/calling-a-webhook-on-a-milestone.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.
