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

# Overview & objects

> How actions, attributes, and Data Steps fit together, plus the shared object schemas the endpoint pages reference.

[Actions](/en/api-reference/actions) and [Attributes](/en/api-reference/attributes) are both configured outbound API calls. An **Action** runs when a [Rulebook](/en/automations/rulebook) Tool node invokes it. An **Attribute** runs automatically at the start of a conversation to load context (for example, a `GetUserInfo` lookup). Use these public routes to create, read, update, delete, and test both from your backend, so a workspace can be set up entirely through the API instead of the dashboard.

<Info>
  The wire-format paths use `/hc-tools` and `/api-function-configs` because that is the current controller contract. In this reference we call them **actions**, **attributes**, and **data steps** because that is what they represent in the product.
</Info>

<Note>
  An Action and an Attribute are the same resource, distinguished by one field:

  * `alwaysGet: false`: an **Action**, invoked by a rule.
  * `alwaysGet: true`: an **Attribute**, fetched automatically each conversation.

  The list route returns both. Filter on `alwaysGet` to separate them.
</Note>

## How the pieces fit

An action or attribute holds the name, description, and typed input and output schema. Its actual HTTP calls live in one or more **Data Steps** (`api-function-configs`) linked by `toolId` and run in `stepNumber` order, each feeding its extracted output into the next.

```mermaid theme={null}
flowchart LR
    A["Action / Attribute<br/>(name, input + output schema)"] --> S1["Data Step 1<br/>HTTP call"]
    S1 --> S2["Data Step 2<br/>HTTP call"]
    S2 --> OUT["Typed output<br/>(output schema)"]
```

<Warning>
  A rule gets nothing back from an Action unless the Action declares an **output schema**. Set `outputSchema` on the action (via [Update action](/en/api-reference/update-action)) and map each output field to a Data Step response path. You can inspect this through the API to catch the gotcha before wiring the rule.
</Warning>

## Setup order

Creating a working action or attribute is a short sequence, the same one the dashboard performs:

<Steps>
  <Step title="Create the action or attribute">
    `POST /v2/hc-tools/public` with `name` and `alwaysGet`.
  </Step>

  <Step title="Add the input and output schema">
    `PATCH /v2/hc-tools/{id}/public` with `inputSchema` and `outputSchema`.
  </Step>

  <Step title="Add one or more Data Steps">
    `POST /v2/api-function-configs/public` with `toolId` set and a `stepNumber`.
  </Step>

  <Step title="Attach to agents (attributes only)">
    `POST /v2/hc-tools/junctions/public` to assign the attribute to agents. Attributes only run for assigned agents. For actions, skip this and wire the action into a [Rulebook](/en/automations/rulebook) Tool node instead; action assignments are stored but not enforced at runtime.
  </Step>

  <Step title="Test it">
    `POST /v2/hc-tools/{id}/test-run/public` to run the whole chain, or `POST /v2/api-function-configs/test-run/public` to test one HTTP call.
  </Step>
</Steps>

## Endpoint map

Each `hc-tools` route is documented twice, once per type, since the same endpoint serves both.

| Method   | Path                                       | Scope   | Reference                                                                                                                     |
| -------- | ------------------------------------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `GET`    | `/v2/hc-tools/public`                      | `read`  | [List actions](/en/api-reference/list-actions) · [List attributes](/en/api-reference/list-attributes)                         |
| `GET`    | `/v2/hc-tools/:id/public`                  | `read`  | [Get action](/en/api-reference/get-action) · [Get attribute](/en/api-reference/get-attribute)                                 |
| `POST`   | `/v2/hc-tools/public`                      | `write` | [Create action](/en/api-reference/create-action) · [Create attribute](/en/api-reference/create-attribute)                     |
| `PATCH`  | `/v2/hc-tools/:id/public`                  | `write` | [Update action](/en/api-reference/update-action) · [Update attribute](/en/api-reference/update-attribute)                     |
| `DELETE` | `/v2/hc-tools/:id/public`                  | `write` | [Delete action](/en/api-reference/delete-action) · [Delete attribute](/en/api-reference/delete-attribute)                     |
| `POST`   | `/v2/hc-tools/:id/test-run/public`         | `write` | [Test action](/en/api-reference/test-action) · [Test attribute](/en/api-reference/test-attribute)                             |
| `GET`    | `/v2/hc-tools/:id/junctions/public`        | `read`  | [Action assignments](/en/api-reference/list-action-agents) · [Attribute assignments](/en/api-reference/list-attribute-agents) |
| `POST`   | `/v2/hc-tools/junctions/public`            | `write` | [Assign actions](/en/api-reference/assign-action-agents) · [Assign attributes](/en/api-reference/assign-attribute-agents)     |
| `GET`    | `/v2/api-function-configs/public`          | `read`  | [List data steps](/en/api-reference/list-data-steps)                                                                          |
| `GET`    | `/v2/api-function-configs/:id/public`      | `read`  | [Get data step](/en/api-reference/get-data-step)                                                                              |
| `POST`   | `/v2/api-function-configs/public`          | `write` | [Create data step](/en/api-reference/create-data-step)                                                                        |
| `PATCH`  | `/v2/api-function-configs/:id/public`      | `write` | [Update data step](/en/api-reference/update-data-step)                                                                        |
| `DELETE` | `/v2/api-function-configs/:id/public`      | `write` | [Delete data step](/en/api-reference/delete-data-step)                                                                        |
| `POST`   | `/v2/api-function-configs/test-run/public` | `write` | [Test data step](/en/api-reference/test-data-step)                                                                            |

## Action or Attribute object

<ResponseField name="id" type="string">
  Action or attribute ID.
</ResponseField>

<ResponseField name="createdAt" type="string">
  ISO 8601 creation timestamp.
</ResponseField>

<ResponseField name="companyId" type="string">
  Workspace ID that owns the record.
</ResponseField>

<ResponseField name="name" type="string">
  Display name.
</ResponseField>

<ResponseField name="description" type="string | null">
  Human-readable description. Read by your team, not used for routing.
</ResponseField>

<ResponseField name="alwaysGet" type="boolean">
  `false` for an Action (rule-invoked), `true` for an Attribute (fetched automatically each conversation).
</ResponseField>

<ResponseField name="source" type="string | null">
  Optional source. Current values include `ui`, `api`, `widget`, and integration providers such as `zendesk` and `intercom`.
</ResponseField>

<ResponseField name="inputSchema" type="InputSchemaField[]">
  Typed inputs the action or attribute expects. Set through the update route.
</ResponseField>

<ResponseField name="outputSchema" type="OutputSchemaField[]">
  Typed outputs the action or attribute returns. Set through the update route.
</ResponseField>

<ResponseField name="internalHandler" type="string | null">
  Set when the record is backed by a built-in integration handler instead of Data Steps. Read-only through the public API.
</ResponseField>

## InputSchemaField object

<ResponseField name="name" type="string">
  Field name.
</ResponseField>

<ResponseField name="dataType" type="string">
  Current values are `string`, `number`, `boolean`, `array`, `object`, and `date`.
</ResponseField>

<ResponseField name="required" type="boolean">
  Whether the field is required.
</ResponseField>

<ResponseField name="path" type="string">
  Optional runtime path to bind the value from.
</ResponseField>

<ResponseField name="value" type="any">
  Optional literal value.
</ResponseField>

<ResponseField name="source" type="string">
  Optional field source. Current values are `metadata`, `jwt`, and `apiResponse`.
</ResponseField>

<ResponseField name="defaultValue" type="any">
  Optional default value.
</ResponseField>

<ResponseField name="autoBindPath" type="string">
  Optional path to auto-bind from runtime context.
</ResponseField>

## OutputSchemaField object

<ResponseField name="name" type="string">
  Output field name.
</ResponseField>

<ResponseField name="dataType" type="string">
  Current values are `string`, `number`, `boolean`, `array`, `object`, and `date`.
</ResponseField>

<ResponseField name="path" type="string">
  Path into the accumulated Data Step responses to read this value from.
</ResponseField>

<ResponseField name="sendToLlm" type="boolean">
  The "Visible to AI" flag. When `true`, the resolved value is exposed to the agent. Applies to attributes.
</ResponseField>

<ResponseField name="source" type="string">
  Optional field source. Current values are `metadata`, `jwt`, and `apiResponse`.
</ResponseField>

## Data Step object

Returned by the Data Step routes. Sensitive header and body values are masked on read (see below).

<ResponseField name="id" type="string">
  Data Step ID.
</ResponseField>

<ResponseField name="createdAt" type="string">
  ISO 8601 creation timestamp.
</ResponseField>

<ResponseField name="companyId" type="string">
  Workspace ID that owns the Data Step.
</ResponseField>

<ResponseField name="name" type="string">
  Step name.
</ResponseField>

<ResponseField name="hcToolId" type="string">
  ID of the action or attribute this step belongs to.
</ResponseField>

<ResponseField name="stepNumber" type="number | null">
  Position of the step in the chain. Steps run in ascending order.
</ResponseField>

<ResponseField name="requestUrl" type="string">
  Request URL. Supports `{{placeholder}}` interpolation from inputs and earlier steps.
</ResponseField>

<ResponseField name="requestMethod" type="string">
  HTTP verb, for example `GET`, `POST`, `PUT`, `PATCH`, or `DELETE`.
</ResponseField>

<ResponseField name="requestHeaders" type="object | null">
  Request headers. Values are wrapped for masking (see below).
</ResponseField>

<ResponseField name="requestBody" type="object | null">
  Request body. Values are wrapped for masking (see below).
</ResponseField>

<ResponseField name="responseMapping" type="ResponseMapping">
  Map of output keys to paths in the HTTP response (the "Save From Response" mapping).
</ResponseField>

## ResponseMapping object

A map of output key to either a response path string, or an object with a path and data type. A path of `"."` means the entire response body.

```json theme={null}
{
  "balance": "data.available_balance",
  "currency": { "path": "data.currency", "dataType": "string" }
}
```

## Sensitive values and masking

Header and body values can be marked sensitive (for example, an API key). On read, a sensitive value comes back as `{ "hide": true, "value": "********" }`. Non-sensitive values come back as `{ "hide": false, "value": <value> }`.

<Note>
  When you update a Data Step, you can send the masked `"********"` back unchanged and the stored secret is preserved. Send a new string to replace it. To store a value as sensitive, send `{ "hide": true, "value": "<secret>" }`.
</Note>

## Action or Attribute test-run result

Returned by [Test action](/en/api-reference/test-action) and [Test attribute](/en/api-reference/test-attribute).

<ResponseField name="toolName" type="string">
  Name of the action or attribute that ran.
</ResponseField>

<ResponseField name="id" type="string">
  Action or attribute ID.
</ResponseField>

<ResponseField name="name" type="string">
  Action or attribute name.
</ResponseField>

<ResponseField name="success" type="boolean">
  Whether every Data Step in the chain succeeded.
</ResponseField>

<ResponseField name="extractedData" type="object">
  Final output values, keyed by output field name.
</ResponseField>

<ResponseField name="attributeLlmPolicy" type="object">
  For attributes, a map of output field name to its `sendToLlm` (Visible to AI) flag. Empty for actions.
</ResponseField>

<ResponseField name="results" type="object[]">
  Per-step results, including the resolved request and each step's extracted data.
</ResponseField>

## Data Step test-run result

Returned by [Test data step](/en/api-reference/test-data-step).

<ResponseField name="success" type="boolean">
  Whether the HTTP call succeeded.
</ResponseField>

<ResponseField name="statusCode" type="number">
  HTTP status code of the outbound call.
</ResponseField>

<ResponseField name="responseBody" type="any">
  Raw response body from the call.
</ResponseField>

<ResponseField name="error" type="string">
  Present when the call failed.
</ResponseField>

## Agent assignment object

Returned by the [action](/en/api-reference/list-action-agents) and [attribute](/en/api-reference/list-attribute-agents) agent-assignment routes.

<ResponseField name="id" type="string">
  Assignment ID.
</ResponseField>

<ResponseField name="botId" type="string">
  Agent ID the action or attribute is assigned to.
</ResponseField>

<ResponseField name="toolId" type="string">
  Action or attribute ID.
</ResponseField>

<ResponseField name="companyId" type="string">
  Workspace ID.
</ResponseField>

<ResponseField name="channels" type="string[]">
  Channels the assignment applies to, for example `chat` and `email`.
</ResponseField>
