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

# Script API

> JavaScript scripting API reference for request and response hooks

Scripts are JavaScript files stored in `~/.httpmon/scripts/`. Each script has YAML frontmatter inside JS comments and exports `onRequest` and/or `onResponse` hooks.

## Script file format

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
// ---
// name: Add Auth Header
// match:
//   - "*://api.example.com/*"
// enabled: true
// ---

function onRequest(ctx) {
  ctx.headers["Authorization"] = "Bearer my-token";
}

function onResponse(ctx) {
  // modify response here
}
```

The frontmatter is delimited by `// ---` lines. Each YAML line is prefixed with `// `.

## Frontmatter fields

| Field     | Type      | Required | Description                                     |
| --------- | --------- | -------- | ----------------------------------------------- |
| `name`    | string    | yes      | Display name shown in the scripts manager       |
| `match`   | string\[] | yes      | URL patterns to match (glob with `*` wildcards) |
| `enabled` | bool      | no       | Defaults to `true` if omitted                   |

## onRequest(ctx)

Runs before the request is sent upstream.

| Property      | Type   | Access     | Description                        |
| ------------- | ------ | ---------- | ---------------------------------- |
| `ctx.method`  | string | read/write | HTTP method                        |
| `ctx.url`     | string | read/write | Full URL                           |
| `ctx.headers` | object | read/write | Request headers                    |
| `ctx.body`    | string | read/write | Request body                       |
| `ctx.blocked` | bool   | write      | Set to `true` to block the request |

## onResponse(ctx)

Runs before the response reaches the client.

| Property             | Type     | Access     | Description                                  |
| -------------------- | -------- | ---------- | -------------------------------------------- |
| `ctx.status`         | int      | read/write | Status code                                  |
| `ctx.headers`        | object   | read/write | Response headers                             |
| `ctx.body`           | string   | read/write | Response body                                |
| `ctx.respondWith()`  | function |            | Replace the response entirely                |
| `ctx.breakpoint()`   | function |            | Pause the response for interactive editing   |
| `ctx.readFile(path)` | function |            | Read a file relative to the script directory |

## ctx.respondWith(options)

Short-circuits the normal proxy flow and returns a synthetic response. Available in both `onRequest` and `onResponse`.

In `onRequest`, calling `respondWith` stops script execution immediately. The request is never sent upstream. In `onResponse`, execution continues after the call.

| Option    | Type   | Description                                        |
| --------- | ------ | -------------------------------------------------- |
| `status`  | int    | Response status code (defaults to `200`)           |
| `body`    | string | Response body                                      |
| `headers` | object | Response headers as key-value pairs                |
| `file`    | string | Path to a local file to serve as the response body |

When you use `file`, the content-type is auto-detected from the file extension. The `file` and `body` options are mutually exclusive.

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
function onRequest(ctx) {
  ctx.respondWith({
    status: 200,
    body: '{"mocked": true}',
    headers: {"Content-Type": "application/json"}
  });
}
```

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
function onRequest(ctx) {
  ctx.respondWith({file: "./mock.json"});
}
```

## ctx.breakpoint()

Pauses the flow for interactive editing in the TUI. You can inspect and modify headers and body before the flow continues.

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
function onRequest(ctx) {
  ctx.breakpoint();
}
```

## ctx.readFile(path)

Reads a file from disk and returns its contents as a string. Returns `null` if the file does not exist. Paths are resolved relative to the script's directory.

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
function onRequest(ctx) {
  var data = ctx.readFile("./fixtures/response.json");
  ctx.respondWith({body: data});
}
```

## URL match patterns

Match patterns use glob syntax with `*` wildcards. The format is `scheme://host/path`.

* `*` in the scheme position matches any scheme (http or https).
* `*` in the host matches a single domain label (`*.example.com` matches `api.example.com` but not `a.b.example.com`).
* `*` in the path matches any substring including slashes.

Matching is case-insensitive.

| Pattern                   | Matches                                  |
| ------------------------- | ---------------------------------------- |
| `*://api.example.com/*`   | Any request to api.example.com           |
| `*://*.example.com/api/*` | Any subdomain of example.com under /api/ |
| `*://*/*`                 | All URLs                                 |
