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

# Preset Webhook Parameters

> Send fixed query string and body values with a webhook tool without exposing them to the LLM.

Webhook tool parameters declared under `body_parameters`, `path_parameters`, and `query_parameters` are advertised to the model: the assistant decides their values at call time, and can get them wrong or omit them.

Preset parameters are the opposite. `preset_body_fields` and `preset_query_params` are supplied by the assistant configuration, never appear in the tool definition the model sees, and are attached to every call the tool makes. Use them for values the model has no business choosing — an account identifier, an API key, a tenant or channel tag, a feature flag.

***

## How preset parameters behave

* **Invisible to the model.** They are not part of the tool schema, so the LLM can neither read them nor be prompted into changing them.
* **Always applied.** Every invocation of the tool carries them.
* **They win on conflicts.** If a preset key has the same name as a model-supplied parameter, the preset value replaces it.
* **They are templated.** Values go through the same mustache templating as the rest of the tool config, so they can carry [dynamic variables](/docs/inference/ai-assistants/dynamic-variables) and [integration secrets](/docs/inference/ai-assistants/integrations).
* **Query values are encoded for you.** `preset_query_params` values are percent-encoded before they are appended to the URL, so a value like `+15551234567` arrives intact. Values templated directly into the `url` are not.
* **`preset_body_fields` needs a body.** `GET` requests are sent without a body, so preset body fields are dropped on `GET` tools. Use `preset_query_params` instead.

***

## Configuration

| Field                 | Type   | Description                                   |
| --------------------- | ------ | --------------------------------------------- |
| `preset_body_fields`  | object | Key/value pairs merged into the request body. |
| `preset_query_params` | object | Key/value pairs merged into the query string. |

Both accept arbitrary keys. String values are mustache-templated before the request is sent.

***

## Examples

### Tag every request with a fixed value

Here the model supplies `order_id`; `source` and `account_id` are attached by the configuration, and the assistant never sees them:

```json theme={null}
{
  "type": "webhook",
  "webhook": {
    "name": "lookup_order",
    "description": "Look up the status of a customer order.",
    "url": "https://your-backend.com/orders/status",
    "method": "POST",
    "body_parameters": {
      "type": "object",
      "properties": {
        "order_id": {
          "type": "string",
          "description": "The order number the customer gave."
        }
      },
      "required": ["order_id"]
    },
    "preset_body_fields": {
      "source": "telnyx-assistant",
      "account_id": "{{customer_id}}"
    }
  }
}
```

Your backend receives:

```json theme={null}
{
  "order_id": "A-4471",
  "source": "telnyx-assistant",
  "account_id": "cus_8123"
}
```

### Pass the caller's number as a query parameter

`preset_query_params` is the safest way to forward a phone number, because the value is percent-encoded rather than pasted into the URL:

```json theme={null}
{
  "type": "webhook",
  "webhook": {
    "name": "recent_tickets",
    "description": "List the caller's recent support tickets.",
    "url": "https://your-backend.com/tickets",
    "method": "GET",
    "preset_query_params": {
      "caller": "{{telnyx_end_user_target}}",
      "channel": "voice"
    }
  }
}
```

The request becomes `GET https://your-backend.com/tickets?caller=%2B15551234567&channel=voice`.

### Send a secret the model can never read

Combine preset parameters with [integration secrets](/docs/inference/ai-assistants/integrations) when an API expects credentials in the query string or body rather than in a header:

```json theme={null}
{
  "type": "webhook",
  "webhook": {
    "name": "check_inventory",
    "description": "Check whether an item is in stock.",
    "url": "https://your-backend.com/inventory",
    "method": "GET",
    "query_parameters": {
      "type": "object",
      "properties": {
        "sku": {
          "type": "string",
          "description": "The item SKU to check."
        }
      },
      "required": ["sku"]
    },
    "preset_query_params": {
      "api_key": "{{#integration_secret}}inventory-api-key{{/integration_secret}}"
    }
  }
}
```

<Note>
  Prefer a header for credentials when the API supports one — query strings are more likely to be logged by proxies and servers along the way. Webhook tool headers support the same integration secret templating.
</Note>

***

## Related resources

* [Voice AI Assistant API Reference](/api-reference/assistants/create-an-assistant#webhooktool) - Complete webhook tool API documentation, including `preset_body_fields` and `preset_query_params`.
* [Dynamic Variables](/docs/inference/ai-assistants/dynamic-variables) - Values resolved per conversation that you can template into preset parameters.
* [Integrations](/docs/inference/ai-assistants/integrations) - Store credentials as integration secrets and reference them from tool configuration.
* [Async Tools & Deferred Context](/docs/inference/ai-assistants/async-tools) - Keep the conversation moving while a webhook tool runs.
