> ## Documentation Index
> Fetch the complete documentation index at: https://requestscript.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Contracts

> Save named, versioned scripts on the server and invoke them with parameters.

A **contract** is a script that you save on the server once and invoke as many times as you like, passing different parameters each time. Where a [request](/language/scripts#request-scripts) is a one-off, a contract is a reusable, named operation, much like an API endpoint that you define yourself.

```kotlin theme={null}
contract shop.orders.LineTotal@2(item: object, taxRate: decimal(1, 4)) {
    // Price a single line item
    var subtotal: decimal = 0
    subtotal = subtotal + item.price * item.quantity
    const total = subtotal + subtotal * taxRate

    if (total > 100 && item.giftWrap != true) {
        return { total: total, note: "Free shipping" }
    }

    return {
        total: total,
        note: "Taxed at ${taxRate * 100}%",
    }
}
```

Invoked with these parameters:

```json theme={null}
{ "parameters": { "item": { "price": 9.99, "quantity": 2 }, "taxRate": 0.0825 } }
```

it returns:

```json theme={null}
{ "returnValue": { "total": 21.62835, "note": "Taxed at 8.25%" } }
```

## Lifecycle

**1. Write**

Write a script that starts with a `contract` declaration giving its path, name, optional version and parameters. See [Writing contracts](#writing-contracts) below.

**2. Save**

Send the script to [`POST /contracts`](/reference/http-api#save-a-contract). The server checks that it parses and stores it.

**3. Invoke**

Post JSON parameters to `/run/<path>/<Name>`. See [Invoking contracts](/contracts/invoking).

**4. Evolve**

Contracts are immutable. To change one, save a new version. See [Versioning](/contracts/versioning).

## Writing contracts

A contract declaration has a path, a name, an optional version and an optional parameter list:

```kotlin theme={null}
contract path.to.MyContract@1.2.3(name: string, tags: []string,) {
    return "Hello ${name}"
}
```

### Path and name

The path is a dot-separated prefix that groups related contracts, and the name is the final segment. Together they identify the contract. Two contracts can share a name if their paths differ:

```kotlin theme={null}
contract billing.invoices.Summary { return "invoices" }
```

```kotlin theme={null}
contract billing.payments.Summary { return "payments" }
```

The path is optional, and path segments may be any word, including keywords.

### Parameters

Parameters are `name: type` pairs, separated by commas, with an optional trailing comma. Any [type](/language/types) can be used, including `decimal(p, s)` and list types.

```kotlin theme={null}
contract orders.Create(customerId: int64, items: []object, note: string) {
    // ...
}
```

* Parameter names must be unique.
* A contract without parameters leaves out the parentheses. Empty parentheses, `()`, are an error.
* Parameters are [`const`](/language/variables#const) inside the body. You can't reassign them, but you can modify the contents of object and list parameters.

### Body

The body is the same as any script body: variables, [resources](/resources/overview), `if` statements and a `return`. The returned value becomes the `returnValue` of each invocation.

## Contracts compared to requests

| | Request | Contract |
| - | - | - |
| Declared with | `request Name` | `contract path.Name@version(params)` |
| Parameters | None | Optional, typed |
| Stored on the server | No | Yes |
| Run with | `POST /run` with the script | `POST /run/<path>/<Name>` with JSON parameters |
| Versioned | No | Yes |

Sending a contract script to `POST /run`, or a request script to `POST /contracts`, is rejected with an `InvalidScript` error.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.