# uip is connectors builder activity hook

> Syntax and options for creating, reading, and managing JavaScript pre/post-request hooks on a connector's activities.

`uip is connectors builder activity hook` manages JavaScript transformation hooks — the connector's escape hatch for request/response logic that a declarative field or parameter can't express. It's a nested sub-group under [`activity`](./uip-is-connectors-builder-activity.md), split onto its own page because of the amount of runtime-context documentation a hook author needs. See [Connectors builder](./uip-is-connectors-builder.md) for the shared concepts (connector-directory resolution, the typical authoring flow) that apply here too.

Hook files live under `app/element/hooks/` in the connector directory. A hook can attach to a specific resource+method (a *resource hook*) or run for every request (a *global* hook, `--global`).

## Synopsis

```text
uip is connectors builder activity hook list [--connector-dir <path>]
uip is connectors builder activity hook get <filename> [--connector-dir <path>]
uip is connectors builder activity hook create --hook-type <preRequest|postRequest> [options...] [--connector-dir <path>]
uip is connectors builder activity hook delete <filename> [--connector-dir <path>]
```

## uip is connectors builder activity hook list

List the JavaScript hook files under `app/element/hooks/` and whether each is referenced in `element.json`.

### Options

| Long | Value | Description |
|---|---|---|
| `--connector-dir <path>` | path | Connector directory. |

### Example

```bash
uip is connectors builder activity hook list
```

### Data shape (--output json)

```json
{
  "Code": "HookList",
  "Data": {
    "ConnectorRoot": "/work/periodic-design-acme",
    "Hooks": [
      { "filename": "resource-account-GET-postRequest.js", "registered": true }
    ]
  }
}
```

A hook file that exists on disk but has `registered: false` is orphaned — its code runs for nothing until it's re-registered (re-run `hook create` against it, or wire it manually into `element.json`).

## uip is connectors builder activity hook get

Read a single hook file's source and registration status.

### Arguments

| Name | Required | Purpose |
|---|---|---|
| `<filename>` | yes | Hook filename, e.g. `resource-account-GET-postRequest.js` or `global-preRequest.js`. |

### Options

| Long | Value | Description |
|---|---|---|
| `--connector-dir <path>` | path | Connector directory. |

### Example

```bash
uip is connectors builder activity hook get resource-account-GET-postRequest.js
```

### Data shape (--output json)

```json
{
  "Code": "Hook",
  "Data": {
    "ConnectorRoot": "/work/periodic-design-acme",
    "Filename": "resource-account-GET-postRequest.js",
    "Registered": true,
    "Code": "done({ response_body });"
  }
}
```

## uip is connectors builder activity hook create

Create a JavaScript hook file and — unless `--no-auto-register` — register its reference in `element.json`.

### Options

| Long | Value | Required | Description |
|---|---|---|---|
| `--resource-name <name>` | string | conditionally* | Resource the hook attaches to. Not needed with `--global`. |
| `--method <method>` | string | conditionally* | HTTP method of the resource. Not needed with `--global`. |
| `--path <internalPath>` | string | no | Resource internal path (the unique `element.json` resource path), to disambiguate when a list resource and a by-id resource share a method (e.g. `/contacts/{id}`) — vendor paths aren't unique, the internal path is. |
| `--hook-type <type>` | `preRequest`\|`postRequest` | **yes** | Hook phase. |
| `--custom-code <js>` | string | no** | The hook body, inline. Mutually exclusive with `--custom-code-file`. |
| `--custom-code-file <path>` | path | no** | Path to a `.js` file whose contents become the hook body. Preferred over `--custom-code`. |
| `--description <text>` | string | no | Comment placed at the top of the file. |
| `--context-params <list>` | string | no | Override the `contextParams` string on the hook reference. |
| `--no-auto-register` | flag | no | Write the file but do not register it in `element.json`. |
| `--global` | flag | no | Register a connector-wide hook in the top-level `hooks[]` array, instead of attaching to one resource+method. |
| `--connector-dir <path>` | path | no | Connector directory. |

\* Commander can't express "required unless `--global`" declaratively — both options are plain (not `requiredOption`), and the underlying service enforces the resource-hook case at runtime, failing if `--resource-name`/`--method` are missing on a non-global hook.

\*\* Passing both `--custom-code` and `--custom-code-file` is an error. You write the hook body yourself (or have an agent write it) — the CLI only places and registers the file; it does not generate hook logic.

### Hook body context

A hook returns through `done({...})`, never a bare `return`, and must call `done()` on every code path. The CLI auto-binds exactly the variables your body references; override the set with `--context-params` (list `multipart_hook_context_items` explicitly if you use it).

**`preRequest` — read-only:**

`request_method`, `request_headers`, `request_path`, `request_path_variables`, `request_parameters`, `request_body`, `request_body_map` (curated request body as a map — read fields directly), `request_body_raw`, `request_vendor_body_map`, `request_vendor_url`, `request_expression` (CEQL where, as `[{attribute,value,operator}]`), `request_previous_response`, `request_previous_response_headers`, `object_name`, `vendor_object_name`, `configuration` (read-only in this phase).

**`preRequest` — read/write** (edit, then return only the keys you changed; a bare `done()` passes everything through unmodified):

`request_vendor_method`, `request_vendor_headers`, `request_vendor_path`, `request_vendor_parameters`, `request_vendor_body` (a string on read; string, list, or map on write), `request_root_key`, `multipart_hook_context_items`.

**`preRequest` — `done()`-only keys:** `continue` (`false` skips the vendor call but still runs `postRequest`), `response_status_code` / `response_body` / `response_body_raw` / `response_error_message` (short-circuit a response without calling the vendor at all).

**`postRequest` — read-only:**

`response_iserror` (`true` unless the HTTP status is 200–207), `response_body_map`, `response_body_raw_map`, every `request_*` variable as actually sent to the vendor, `request_previous_response`, `request_previous_response_headers`.

**`postRequest` — read/write** (edit and return the changed keys):

`response_body` (map), `response_body_raw` (string), `response_headers`, `response_status_code`, `response_root_key`, `configuration` (writable in this phase — see below), `multipart_hook_context_items`.

**`postRequest` — `done()`-only keys:** `response_error_message` (converts the call to an error; status comes from `response_status_code`, else 400), `connection_identity` (set the connection's display name), `metadata_merge` / `merge_objects` (object-discovery resources only).

**Key rules:**

- `configuration` is read-only in `preRequest`, read/write in `postRequest`. To persist a derived per-connection value (e.g. a base URL computed from a token), write it in a `postRequest` hook: `done({ configuration: { 'base.url': url } })`. Writing `configuration` in `preRequest` has no effect.
- A `request_vendor_path` that starts with `http` becomes the full request URL, bypassing the connector's configured base URL.
- Success is strictly HTTP 200–207. `response_iserror` is derived and read-only — returning a different value for it does nothing.

**Engine:** the hook runtime (Denali) supports modern JavaScript (`?.`, `??`, `async`/`await`) and `require()` for a fixed module set: `axios` (for secondary HTTP calls from inside a hook), `crypto`, `url`, `querystring`, `util`, `buffer`, `zlib`, `lodash`, `jmespath`, `moment`.

For guidance on *when* (and when not) to reach for a hook instead of a declarative field/param, the CLI points to the `uipath-connector-builder` skill's `references/hooks.md` — see [`uip skills`](./uip-skills.md).

### Examples

```bash
# Post-request hook for a resource, from an agent-written JS file
uip is connectors builder activity hook create \
  --resource-name Account --method GET --hook-type postRequest \
  --custom-code-file ./account-postRequest.js

# Global pre-request hook
uip is connectors builder activity hook create \
  --hook-type preRequest --global --custom-code-file ./my-hook.js
```

### Data shape (--output json)

```json
{
  "Code": "HookCreated",
  "Data": {
    "ConnectorRoot": "/work/periodic-design-acme",
    "Filename": "resource-Account-GET-postRequest.js",
    "HookType": "postRequest",
    "Method": "GET",
    "ResourceName": "Account",
    "FilePath": "app/element/hooks/resource-Account-GET-postRequest.js",
    "HookReference": {},
    "RegisteredInElement": true
  }
}
```

For a global hook, `Filename` follows the `global-<hookType>.js` pattern (e.g. `global-preRequest.js`) and `ResourceName`/`Method` are absent.

## uip is connectors builder activity hook delete

Delete a hook file and strip every reference to it from `element.json`.

### Arguments

| Name | Required | Purpose |
|---|---|---|
| `<filename>` | yes | Hook filename to delete. |

### Options

| Long | Value | Description |
|---|---|---|
| `--connector-dir <path>` | path | Connector directory. |

There is no dedicated "edit a hook" verb — delete and re-create, or edit the file on disk directly (a hook file is plain JavaScript, not a generated artifact).

### Example

```bash
uip is connectors builder activity hook delete resource-account-GET-postRequest.js
```

### Data shape (--output json)

```json
{
  "Code": "HookRemoved",
  "Data": {
    "ConnectorRoot": "/work/periodic-design-acme",
    "Filename": "resource-account-GET-postRequest.js",
    "FileDeleted": true,
    "ReferenceRemoved": true
  }
}
```

## Related

- [Activity](./uip-is-connectors-builder-activity.md) — the resource/field/method/param commands a hook attaches to.
- [Connectors builder](./uip-is-connectors-builder.md) — concepts and the four tenant-lifecycle verbs.
- [Auth](./uip-is-connectors-builder-auth.md) — configure the connector's authentication scheme.
- [Trigger & state](./uip-is-connectors-builder-trigger.md) — event triggers and low-level element-file edits.

## See also

- [Integration Service tool overview](./uip-is.md)
- [Global options](./global-options.md)
- [Exit codes](./exit-codes.md)
