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

# Custom Tools

> Define HTTP API tools for your agents

Custom tools let Duckie call HTTP endpoints that you define. Use them for internal services, third-party APIs, or any API action that is not already covered by a connected integration.

## Create a Custom Tool

<Steps>
  <Step title="Navigate to Tools">
    Go to **Build → Tools**, then open the **Custom Tools** tab.
  </Step>

  <Step title="Create the tool">
    Click **Tool** to open the custom tool dialog.
  </Step>

  <Step title="Add basic details">
    Enter a name and description. The description helps the agent understand when to use the tool.
  </Step>

  <Step title="Configure the endpoint">
    Choose a method and enter the endpoint URL.

    Supported methods are `GET`, `POST`, `PUT`, `PATCH`, and `DELETE`.
  </Step>

  <Step title="Choose authentication">
    Select an OAuth credential for OAuth 2.0 client credentials, or leave **No OAuth** and add authentication headers manually.
  </Step>

  <Step title="Add headers">
    Add any non-OAuth headers the endpoint requires, such as API keys, vendor headers, content type headers, or request-specific values the agent should generate.
  </Step>

  <Step title="Define parameters">
    Add the inputs the tool accepts. Parameters can be AI-generated or fixed values.
  </Step>

  <Step title="Test the tool">
    Use **Test Tool** with sample values before enabling the tool for an agent or assistant.
  </Step>
</Steps>

## Enable a Custom Tool

After creating a custom tool, choose where it can be used:

| Surface                | How to use the tool                                                |
| ---------------------- | ------------------------------------------------------------------ |
| **Agents**             | Open the agent's tool access settings and enable the custom tool   |
| **Internal assistant** | Open **Settings > Assistant** and enable the custom tool           |
| **Workflows**          | Add an Action node, open the **Custom** tab, and select the tool   |
| **Runbooks**           | Reference the tool in the runbook after the agent has access to it |

## Endpoint Safety

Custom tool endpoint URLs must use `http` or `https`. Duckie blocks local, private, and internal network addresses before making server-side requests.

## Authentication

Custom tools can call endpoints with no authentication, fixed headers, AI-generated headers, or OAuth 2.0 client credentials.

| Method                           | Use for                                                                                                                       | How to configure                                                                                                                   |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| **No authentication**            | Public endpoints or endpoints that only require request parameters                                                            | Leave **Authentication** set to **No OAuth** and do not add authentication headers                                                 |
| **Fixed headers**                | API keys, static bearer tokens, Basic auth, content type headers, and other values that should be sent the same way each time | Add the header in **Headers**, choose **Fixed value**, and enter the value Duckie should send                                      |
| **AI-generated headers**         | Header values that depend on the current request and should be supplied by the agent when the tool runs                       | Add the header in **Headers**, choose **AI-generated**, describe the expected value, and mark it required if the endpoint needs it |
| **OAuth 2.0 client credentials** | APIs that issue access tokens from a client ID and client secret                                                              | Create or select an OAuth credential in **Authentication**                                                                         |

### Header value sources

Each custom header can use one of two value sources:

| Value source     | Behavior                                                                                                                       |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Fixed value**  | Duckie sends the configured value whenever the tool runs. Fixed headers support parameter placeholders and org variables.      |
| **AI-generated** | The agent supplies the header value when the tool runs. Use the description to explain exactly what the header should contain. |

Use fixed headers when the API expects a constant value.

**Bearer token:**

```text theme={null}
Authorization: Bearer {{org.api_key}}
```

**API key header:**

```text theme={null}
X-API-Key: {{org.api_key}}
```

**Basic auth:**

```text theme={null}
Authorization: Basic <base64-encoded-username-and-password>
```

For Basic auth, enter the final encoded `Authorization` value.

Use AI-generated headers when the header value should be inferred from the current request instead of stored in the tool configuration or sent as a body/query parameter.

**Request-specific routing header:**

```text theme={null}
X-Customer-Tier: enterprise
```

When a tool has AI-generated headers, Duckie exposes those headers to the agent as `api_headers`, sends only the header names configured on the tool, and merges the generated values into the outbound request. Do not add a normal parameter named `api_headers` to a custom tool that also has AI-generated headers; that name is reserved for header values.

### OAuth 2.0 client credentials

Use OAuth credentials when the API requires Duckie to request an access token before calling the endpoint.

To create a credential, click **New credential** in the custom tool dialog and enter:

| Field             | Description                                                 |
| ----------------- | ----------------------------------------------------------- |
| **Name**          | A reusable label for the credential                         |
| **Token URL**     | The HTTPS endpoint Duckie calls to request the access token |
| **Client ID**     | The OAuth client ID                                         |
| **Client Secret** | The OAuth client secret                                     |
| **Scope**         | Optional OAuth scope value                                  |

Duckie requests tokens with `grant_type=client_credentials`, caches valid access tokens, and sends the resolved token as an `Authorization` header when the custom tool runs. If the token response does not include a token type, Duckie uses `Bearer`.

The OAuth token URL must use `https`, cannot contain org variables, and must not resolve to a local, private, or internal network address.

<Note>
  If you select an OAuth credential, remove any manual `Authorization` header before saving the custom tool.
</Note>

## Parameters

Parameters describe the values Duckie can send to your endpoint.

| Type      | Use for                                                           |
| --------- | ----------------------------------------------------------------- |
| `string`  | IDs, names, email addresses, text values, and other plain strings |
| `number`  | Numeric values such as amounts, counts, and limits                |
| `boolean` | `true` or `false` flags                                           |
| `object`  | Structured JSON objects                                           |
| `array`   | Lists of values                                                   |

Each parameter can use one of two value sources:

| Value source     | Behavior                                                                                                                                        |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| **AI-generated** | The agent supplies the value. Use the description to explain what the parameter should contain.                                                 |
| **Fixed value**  | Duckie always sends the configured value. Use this for constants, IDs, flags, org variables, or run metadata values the agent should not infer. |

Parameters can be required or optional. Parameters referenced in endpoint or header templates are automatically required.

## Template Placeholders

Use `{{param}}` syntax in URLs and headers when a parameter should be inserted into the request target or header value.

**URL with parameter:**

```text theme={null}
https://api.example.com/orders/{{order_id}}
```

**Header with parameter:**

```text theme={null}
X-Customer-Email: {{email}}
```

Duckie automatically creates required parameters for placeholders it finds in the URL or headers.

For `POST`, `PUT`, and `PATCH` requests, non-placeholder parameters are sent in the request body. For `GET` and `DELETE` requests, non-placeholder parameters are sent as query parameters.

## Org Variables

Org variables can be used in URL paths, URL query strings, headers, and fixed values with `{{org.variable_name}}` syntax.

Keep the endpoint scheme and hostname literal, such as `https://api.example.com`. Duckie validates the endpoint host before resolving org variables, then resolves org variables in the path, query string, and headers before making the request.

**URL path with org variable:**

```text theme={null}
https://api.example.com/{{org.region}}/orders/{{order_id}}
```

**Header with org variable:**

```text theme={null}
Authorization: Bearer {{org.api_key}}
```

**Fixed parameter value with org variable:**

```text theme={null}
{{org.default_team_id}}
```

When using an org variable as a fixed parameter value, make the whole value the org variable reference. Duckie does not expand org variables embedded inside longer AI-generated parameter values.

## Context Variables

Context variables let a custom tool use values from the run's metadata. Use `{{context.variable_name}}` as the full fixed value for a parameter.

For example, if a run has metadata with a `phone` field, set the custom tool parameter to:

```text theme={null}
{{context.phone}}
```

Duckie resolves the fixed value before calling the tool, so the agent does not need to generate that parameter.

Context variables also support nested metadata paths:

```text theme={null}
{{context.customer.phone}}
```

To use a context variable in a URL path, query string, or header, route it through a fixed parameter and reference that parameter with normal `{{param}}` placeholders.

**URL path using a context-backed parameter:**

```text theme={null}
Endpoint: https://api.example.com/customers/{{phone}}/orders
Parameter phone fixed value: {{context.phone}}
```

**Header using a context-backed parameter:**

```text theme={null}
Header: X-Customer-Phone: {{phone}}
Parameter phone fixed value: {{context.phone}}
```

When using a context variable as a fixed parameter value, make the whole value the context variable reference. Duckie does not expand context variables embedded inside longer AI-generated parameter values.

## Write Actions and Approvals

Use **Write Action** for tools that change external state, such as updating an account, issuing a refund, creating a ticket, or sending a message.

Use **Requires Approval** when a human should approve the tool call before it runs. When approval is enabled, you can notify specific Slack users or a Slack channel. Leave the notification field empty to use the org-wide default.

## HTTP Timeout

You can set a custom HTTP timeout from 1 to 300 seconds. Leave it blank to use Duckie's default timeout.

## Related Pages

<CardGroup cols={2}>
  <Card title="Agent Configuration" icon="robot" href="/agents/configuration">
    Enable custom tools for agents
  </Card>

  <Card title="Workflow Actions" icon="diagram-project" href="/workflows/nodes-and-conditions">
    Call custom tools from workflows
  </Card>

  <Card title="Duckie as an External Subagent" icon="plug" href="/examples/duckie-as-external-subagent">
    Send a focused Duckie agent's result back to a customer-owned orchestrator.
  </Card>
</CardGroup>
