> For the complete documentation index, see [llms.txt](https://docs.maiagent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maiagent.ai/maiagent-user-guide/en/build/tools/setup_api_tool.md).

# Create API Tools

This guide walks you through creating a new API tool on the platform.

{% hint style="info" %}
You can use MaiAgent's [Tool Builder Agent](https://chat.maiagent.ai/web-chats/27934296-105a-4f3f-80f0-7e9dcdb638d3) to help you create API tools
{% endhint %}

API tools integrate external services and automate workflows.

On this page: [What is an API?](#what-is-api)｜[Quickly create an API tool](#quick-create-api-tool)｜[Reference Agent parameters in query parameters](#query-param-templates)｜[Where to put keys and credentials](#credentials)｜[⚠️ Important reminders](#important-notes)

## **What is an API?** <a href="#what-is-api" id="what-is-api"></a>

An **API (Application Programming Interface)** is a bridge that lets different software systems communicate. Simply put, it acts like a **"server" in the software world**, helping programs exchange information and perform functions.

Imagine dining at a restaurant:

* **You**: The customer who needs food (the application)
* **Kitchen**: Where the food is prepared (the system providing the service)
* **Server**: Relays messages between you and the kitchen (**API**)

You do not need to enter the kitchen yourself. Just tell the server what you want. The server passes your request to the kitchen, then brings the prepared meal to you.

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-affedbd5ccc8692a11a20ce5fc69a39886d0e2d3%2Fplayma%20(10)%20(1).png?alt=media" alt=""><figcaption><p>API workflow diagram</p></figcaption></figure>

API tools help you automate standardized workflows, configure specific response formats, and retrieve information from your systems, for example:

**E-commerce customer service automation**

```
Customer asks about an order ➡️ API retrieves order status ➡️ Automatically reply with delivery progress
```

**Marketing campaign management**

```
New product goes live ➡️ Automatically update the official website ➡️ Send email marketing ➡️ Promote on social platforms
```

**Online course platform:**

```
Student asks about course progress ➡️ API retrieves learning records ➡️ Automatically reply with completion percentage and next class time
```

With API tools, an Agent evolves from a conversational bot into an intelligent assistant that can execute business workflows, greatly improving efficiency and automation.

## Quickly Create an API Tool <a href="#quick-create-api-tool" id="quick-create-api-tool"></a>

### 1. Open the tool management interface <a href="#step-1-enter-tool-management" id="step-1-enter-tool-management"></a>

First, go to <mark style="color:blue;">AI Features</mark> → <mark style="color:blue;">Tools</mark> in the left menu. On the tool list page, click <mark style="color:blue;">Add Tool</mark> in the upper right corner.

### 2. Select the tool type <a href="#step-2-select-tool-type" id="step-2-select-tool-type"></a>

Select API as the tool type.

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-36d929d6f379aadbfe05520796e63d6f8fefaf4f%2FAPI%E5%B7%A5%E5%85%B7.png?alt=media" alt=""><figcaption></figcaption></figure>

### 3. Set the display name <a href="#step-3-set-display-name" id="step-3-set-display-name"></a>

Give the tool a clear display name. Here, use <mark style="color:blue;">google calendar</mark>.

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-1b6a8ebbc7b3900a46b0a20494b1c11c118fbe47%2FAPI%E5%B7%A5%E5%85%B7%20(2).png?alt=media" alt=""><figcaption></figcaption></figure>

* **Purpose**: This name appears in the platform interface for all users to see.
* **Recommendation**: Choose a name that clearly describes the tool's main function so users can understand it. There are no strict formatting requirements for this name.

### 4. Set the tool name <a href="#step-4-set-tool-name" id="step-4-set-tool-name"></a>

Next is the "<mark style="color:blue;">Tool Name</mark>" field.

* **Purpose**: This name is the unique identifier the Agent uses internally to call and identify the tool.
* **Naming rules (important)**:
  * Use English characters.
  * Only the following are allowed:
    * Lowercase letters (a-z)
    * Uppercase letters (A-Z)
    * Numbers (0-9)
    * Underscores (`_`)
    * Hyphens (`-`)
  * **Examples**: `get_weather_forecast`, `database-query-tool`

The image below uses <mark style="color:blue;">google\_calendar\_retriever</mark>

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-e60b90c068677f55f73f007d3f191a41bc3a9e5f%2FAPI%E5%B7%A5%E5%85%B7%20(4).png?alt=media" alt=""><figcaption><p>Defining the API tool name</p></figcaption></figure>

### 5. Write the tool description <a href="#step-5-write-tool-description" id="step-5-write-tool-description"></a>

In the "<mark style="color:blue;">Tool Description</mark>" field, users can provide a clear, detailed explanation of the tool.

* **Why it matters**: A good description helps the Agent understand more accurately:
  * The tool's functions and purpose.
  * When to use the tool.
  * How to interpret the tool's output.
* **Suggested content**: Explain what the tool does, its inputs and outputs, and any usage precautions.
* **Two explanation fields**: The "<mark style="color:blue;">Description</mark>" in the form appears in the tool list for members to read. The "<mark style="color:blue;">Prompt</mark>" provides the Agent with usage instructions, parameter formats, and precautions. After writing the description, click "<mark style="color:blue;">Sync to Prompt</mark>" beside it to copy the description into the prompt field as a starting point (if the description is empty, you will see "Please fill in the description first"). Then add the details the Agent needs.

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-61fe2994e26226077604c4865223522621a0c39c%2FAPI%E5%B7%A5%E5%85%B7%20(5).png?alt=media" alt=""><figcaption><p>Tool description</p></figcaption></figure>

### 6. Detailed API configuration <a href="#step-6-api-configure-details" id="step-6-api-configure-details"></a>

#### a. 🔗 API URL <a href="#api-url" id="api-url"></a>

* Enter the complete URL of the target API endpoint (including `http://` or `https://`).
* **Example**: `https://api.opencalendar.org/data/2.5`
* **Automatically parse pasted cURL**: The field shows the hint "You can paste cURL copied from browser DevTools". In the DevTools Network panel, select "Copy as cURL" for a request and paste it directly into this field. The system parses the URL, headers, and HTTP method and fills in the corresponding fields (showing "URL, headers, and HTTP method parsed from cURL"). When you open the Add Tool dialog, a cURL command already on your clipboard is also imported automatically (the browser must allow clipboard access). If the cURL command uses an unsupported HTTP method, the URL and headers are still filled in; select the method manually. If the format cannot be parsed, you will see "Unable to parse cURL. Please check the format". After pasting, remove personal cookies or one-time tokens from the headers, then use variables as described in [Where to put keys and credentials](#credentials).

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-7c8ec1446f411f007db93eecab4a2de07ee8036e%2FAPI%E5%B7%A5%E5%85%B7%20(6).png?alt=media" alt=""><figcaption></figcaption></figure>

#### b. 📮 HTTP method <a href="#http-method" id="http-method"></a>

* Select the HTTP verb required by the API service from the dropdown:
  * `GET`: Typically retrieves resources.
  * `POST`: Typically creates new resources or submits data.
  * `PUT`: Typically replaces or updates a resource in full.
  * `DELETE`: Typically deletes resources.

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-a96418d1f33a03fb89d7c99d75cbff4200fa5851%2FAPI%E5%B7%A5%E5%85%B7%20(8).png?alt=media" alt=""><figcaption></figcaption></figure>

#### c. 📰 Headers <a href="#headers" id="headers"></a>

Headers are like the "<mark style="color:blue;">envelope</mark>" of a letter. They tell the recipient important information before the actual data is read. **Without the correct headers, an API request may fail authentication, or the recipient may be unable to parse the data correctly.**

**Common uses**:

* Authentication (`Authorization`, `X-API-Key`)
* Specifying the content type (`Content-Type`)
* Specifying the accepted response format (`Accept`)

To configure headers:

* Enter the HTTP headers to include with every request in the "<mark style="color:blue;">Headers (JSON)</mark>" field.
* **Format**: Use a valid JSON object where each key is a header name and each value is the header content (a string). Keep `{}` if no additional headers are needed.
* **Enter the actual key values directly**: For credentials such as API keys and tokens, enter the values provided by the service provider exactly as supplied. The platform does not substitute custom `{{…}}` names. Only specific variables are substituted when the tool is called; see [Where to put keys and credentials](#credentials).
* **Example**:

  ```json
  {
    "Content-Type": "application/json; charset=utf-8",
    "Authorization": "Bearer Paste the token provided by your service provider here",
    "Accept": "application/vnd.github.v3+json"
  }
  ```

{% hint style="info" %}
To authorize the API as the "user in the current conversation" rather than using a shared key: when visitors log in to Web Chat through Keycloak, enable [Use the Keycloak login identity to call tools](/maiagent-user-guide/en/build/choose-channel/web-chat.md#keycloak-token-passthrough) on the conversation platform and add this API's host to the allowlist. The platform then sends the visitor's own Keycloak credentials in the `Authorization` header. In this case, do not also set `Authorization` in Headers (JSON), or your configured value will take precedence.
{% endhint %}

**Sensitive Header Names**: Tool execution records retain the headers from each request. The platform's built-in sensitive headers (`Authorization`, `Proxy-Authorization`, `X-API-Key`, `X-Auth-Token`, `Cookie`, and `Set-Cookie`, listed in the read-only <mark style="color:blue;">Platform Built-in Sensitive Headers</mark>) and headers populated from credentials are always masked. If your API passes keys under other custom names (such as `X-Client-Secret`), enter the name in <mark style="color:blue;">Sensitive Header Names</mark> and press Enter to add it. These header values will then be masked when viewing execution records. Names are case-insensitive, must match exactly, and may contain only English letters, numbers, and `- _ . ~`, with a maximum of 50 names. Settings also apply to existing records; removing a name restores display of its original value.

#### d. 🔎 Query parameters (Query Params) <a href="#query-params" id="query-params"></a>

Query parameters are query strings appended after the question mark in a URL (such as `?format=json&limit=10`) and are sent with each request. Use them for fixed query conditions or API keys that can only be passed through a query string.

* Click "<mark style="color:blue;">Available Context Variables</mark>" to expand the list of supported variables (contact ID, conversation ID, inbox ID, and more).
* **Format**: A valid JSON object where each key is a parameter name and each value is the parameter content (a string).
* Values can be fixed text or use `{{parameter_name}}` to reference a parameter declared in the "Parameters Schema" and filled in by the Agent when calling the tool. This lets you configure query conditions with a fixed first part and a user-provided second part. See [Reference Agent parameters in query parameters](#query-param-templates) below.
* If the provider requires the API key in a query string, put the actual key value here rather than directly after `?` in the API URL. Values configured here do not appear in the "<mark style="color:blue;">Request URL</mark>" in tool execution records; see [Who can see these values](#credential-visibility).
* **Example**:

  ```json
  {
    "$format": "json",
    "$filter": "ProductName eq '{{product_name}}'"
  }
  ```

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-a0552130721b327022bc32313554617846bf0bf7%2Fapi-tool-query-params.png?alt=media" alt="Query parameters field in the tool configuration dialog, with {{product_name}} in a value to reference a parameter"><figcaption><p>Query parameters field and the Available Context Variables list</p></figcaption></figure>

#### e. 🧩 Parameters Schema <a href="#parameters-schema" id="parameters-schema"></a>

**The parameters schema is like an "order form"**, telling the Agent what data it can request from the API and how to request it.

* **Core configuration**: Define which parameters the Agent can or must provide when calling this tool (the content passed to the system for processing), along with their formats.
* **Format**: Use the standard **JSON Schema** format.
* **Key elements**:
  * `type: "object"`: Indicates that the parameters form an object.
  * `properties`: Defines an object for each parameter.
    * **Parameter name** (such as `"search"`): The corresponding object contains the parameter's details.
      * `type`: The parameter's data type (`string`, `integer`, `number`, `boolean`, `array`, `object`).
      * `description`: Instructions explaining the parameter's meaning to the Agent.
      * `default` (optional): The parameter's default value.
      * `enum` (optional): Lists the permitted options if the parameter can only take certain values.
  * `required`: An array containing all **required** parameter names.
* **Do not put keys here**: The parameters schema (including `default` values) is provided to the AI model as the tool definition. Put API keys in "Headers (JSON)" or "Query Params (JSON)".
* **Do not paste sample data**: Define parameters inside `properties`. If you paste sample data such as `{"keyword": "string", "limit": 10}` directly, clicking "<mark style="color:blue;">Confirm</mark>" opens an "<mark style="color:blue;">Error</mark>" dialog explaining that this JSON Schema defines no fields and listing the keys to move into `properties`. Rewrite it as instructed before saving. If the tool needs no parameters, you can save it with the default `{}`.
* **Example** (video and audio search tool):

  ```json
  {
      "type": "object",
      "properties": {
          "limit": {
              "type": "integer",
              "minimum": 1,
              "description": "Maximum number of results returned"
          },
          "fields": {
              "type": "string",
              "description": "Comma-separated list of fields"
          },
          "search": {
              "type": "string",
              "description": "Search keyword"
          }
      },
      "required": ["search"]
  }
  ```

#### f. Path parameters and parameter locations <a href="#path-parameters" id="path-parameters"></a>

Use `{parameter_name}` in the API URL to mark variable parts of the path, such as `/users/{userId}/orders/{orderId}`. To substitute values provided by the Agent into the URL, define parameters with the same names in the "Parameters Schema" and set their location to "<mark style="color:blue;">Path</mark>". Before sending the request, the system URL-encodes each value and substitutes it. For example, `A/B 01` becomes `A%2FB%2001`, so slashes or spaces in a value do not change the URL structure.

**Use case**: A customer service supervisor, Mai, wants the Agent to retrieve a single order from the company's order API using the customer ID and order ID. She creates an API tool, sets both IDs as path parameters, and assigns the tool to the Agent. When a colleague enters "Look up order order-25 for customer customer-01" in a conversation, the Agent places both IDs in the correct URL positions and sends the query. If the order ID is missing, the tool reports the missing value immediately and does not send an incomplete request.

{% stepper %}
{% step %}

### Set an API URL with path parameters <a href="#path-param-step-url" id="path-param-step-url"></a>

Create a tool as described in "Quickly Create an API Tool" above. For practice, use the public httpbin response service and set <mark style="color:blue;">API URL</mark> to:

```
https://httpbin.org/anything/users/{userId}/orders/{orderId}
```

A URL can contain multiple path parameters. After entering it, "<mark style="color:blue;">Detected Path Parameters</mark>" appears below the field and lists `userId, orderId`. If these names are not yet defined in the parameters schema, a red hint also appears: "<mark style="color:blue;">Please define these in the parameters schema</mark>".
{% endstep %}

{% step %}

### Declare parameters with the same names in the schema <a href="#path-param-step-schema" id="path-param-step-schema"></a>

Enter the following in <mark style="color:blue;">Parameters Schema (JSON Schema)</mark>:

```json
{
  "type": "object",
  "properties": {
    "userId": { "type": "string", "description": "Customer ID" },
    "orderId": { "type": "string", "description": "Order ID" }
  },
  "required": ["userId", "orderId"]
}
```

Parameter names must exactly match the names inside the braces in the URL (including case). `required` tells the Agent to provide both values on every call.

After you enter the schema, each parameter appears below it with a location dropdown, initially set to "<mark style="color:blue;">Default</mark>". A red hint appears below the API URL: "<mark style="color:blue;">The following parameters are not located in 'Path'; placeholders in the URL will not be substituted</mark>". This means you still need to complete the next step.

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-fd22abf6d8d512da1b562b409257a40d152e10df%2Fapi-tool-path-params-url-hint.png?alt=media" alt="Add Tool dialog with userId and orderId in the API URL, detected path parameters below, and a red hint that the parameter location is not Path"><figcaption><p>A red hint appears below the API URL while parameter locations are still set to Default</p></figcaption></figure>
{% endstep %}

{% step %}

### Set the parameter location to "Path" <a href="#path-param-step-location" id="path-param-step-location"></a>

Below the parameters schema, change the location dropdowns for both `userId` and `orderId` to "<mark style="color:blue;">Path</mark>".

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-ab2269bc4657f0d2d3ef15768c7817fe6f923eb8%2Fapi-tool-path-params-location-menu.png?alt=media" alt="Expanded location dropdown below the parameters schema, with Default, Path, Query, Body, and Header options"><figcaption><p>Select a location for each parameter from the dropdown</p></figcaption></figure>

After you select the locations, the system automatically adds `"location": "path"` to the parameters schema, and the red hint below the API URL disappears. Check the settings, then click "<mark style="color:blue;">Confirm</mark>" to save the tool.

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-a86225dedbfcf98430095438e3dee00c09eddcc4%2Fapi-tool-path-params-location-set.png?alt=media" alt="Parameters schema with location set to path for both userId and orderId, and both location dropdowns below showing Path"><figcaption><p>Selecting Path also writes the location setting into the parameters schema</p></figcaption></figure>

{% hint style="warning" %}
Parameters left at "<mark style="color:blue;">Default</mark>" are not substituted into the URL. Even if the Agent provides a value, `{userId}` in the URL still has no value, so the tool reports an error and does not send the request. Set every parameter used in the URL to "<mark style="color:blue;">Path</mark>".
{% endhint %}
{% endstep %}

{% step %}

### Assign the tool to an Agent and verify it <a href="#path-param-step-test" id="path-param-step-test"></a>

Follow [Configure tools for an Agent](/maiagent-user-guide/en/build/tools/configure_tools.md) to add the tool to an Agent whose response mode is Agent mode. Then go to "<mark style="color:blue;">Agent Marketplace</mark>" in the left navigation, switch to "<mark style="color:blue;">Organization-built</mark>", select the Agent, and enter "Look up order order-25 for customer customer-01". After the Agent calls the tool, httpbin returns the request URL it actually received: `https://httpbin.org/anything/users/customer-01/orders/order-25`.

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-8fbf496275f08bf616b56673143a7aede4f364d3%2Fapi-tool-path-params-chat.png?alt=media" alt="Agent response showing the customer ID, order ID, and request URL with both IDs substituted"><figcaption><p>The Agent substitutes both IDs into the URL and sends the query</p></figcaption></figure>

To see the URL actually sent on each call, go to "<mark style="color:blue;">AgentOps</mark>" → "<mark style="color:blue;">Tool Execution Records</mark>" in the left navigation. Click the eye icon in the record's actions column to open "<mark style="color:blue;">Details</mark>", then check "<mark style="color:blue;">Request URL</mark>" under "<mark style="color:blue;">Request Information</mark>". The image below shows a call with a customer ID containing a slash and a space (`A/B 01`); the value has been URL-encoded.

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-42bb5fd57f4e3d8aa020f8499b1f77ef9dc246bd%2Fapi-tool-path-params-record.png?alt=media" alt="Tool execution record details with A/B 01 and order#25 as input parameters and A%2FB%2001 and order%2325 in the corresponding request URL segments"><figcaption><p>The request URL in tool execution records shows the encoded path parameters</p></figcaption></figure>

After practicing, replace the public demonstration URL with your company's order API URL.
{% endstep %}
{% endstepper %}

**Parameter location options**

Set a location for each parameter in the schema to determine where its value is placed in the request:

| Location                                 | Description                                                                                                                                                                                                             |
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <mark style="color:blue;">Default</mark> | Keeps the original behavior: GET places values in the query string; POST, PUT, and PATCH place them in the body. DELETE does not include them automatically; explicitly select a location when values need to be passed |
| <mark style="color:blue;">Path</mark>    | Substitutes into `{parameter_name}` with the same name in the API URL                                                                                                                                                   |
| <mark style="color:blue;">Query</mark>   | Appends to the query string after the question mark in the URL                                                                                                                                                          |
| <mark style="color:blue;">Body</mark>    | Places values in the JSON body                                                                                                                                                                                          |
| <mark style="color:blue;">Header</mark>  | Sends an HTTP header using the parameter name; if "Headers (JSON)" already defines a header with the same name (case-insensitive), the configured content takes precedence                                              |

Existing tools without location settings keep their current behavior.

**No request is sent when a path parameter value is missing**

If any path parameter in the URL has no value on a call (the Agent did not provide it, the value is empty, or the parameter's location is not "Path"), the tool stops immediately and reports "Path parameter {orderId} has no value for this call". It does not send a URL containing `{orderId}`. The Agent explains the query failure in the conversation. In "<mark style="color:blue;">Tool Execution Records</mark>", the record has a failed status, "<mark style="color:blue;">Request Information</mark>" contains no request content, and "<mark style="color:blue;">Error Message</mark>" identifies the parameter with the missing value.

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-750f62d0eddb446a5a310c0f0df7ad282742b8c3%2Fapi-tool-path-params-missing.png?alt=media" alt="Tool execution record details with orderId set to null in the input parameters, no request information, and an error stating that path parameter orderId has no value for this call"><figcaption><p>When a path parameter value is missing, the tool sends no request and records the reason for the error</p></figcaption></figure>

**URL syntax restrictions**

* Path parameter names may contain only English letters, numbers, and underscores, and cannot start with a number, for example `{order_id}`. Names such as `{order-id}` cannot be saved.
* Put `{parameter_name}` in the URL path. For values needed in the query string, set the parameter location to "<mark style="color:blue;">Query</mark>" or reference them with `{{parameter_name}}` in [Query parameters](#query-param-templates).
* The API URL cannot use double-brace `{{variable}}` syntax. Saving it opens an "<mark style="color:blue;">Error</mark>" dialog: "Path parameters must use {identifier} syntax." In API tools, use `{{parameter_name}}` in "Headers (JSON)" and "Query Params (JSON)".

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-2504b5ecf2e51c2e9bb2ac09e44dcde725120152%2Fapi-tool-path-params-invalid-syntax.png?alt=media" alt="Request failed with status code 400 shown at the top, and an error dialog in the center stating that path parameters must use {identifier} syntax"><figcaption><p>An API URL containing double braces cannot be saved</p></figcaption></figure>

Google Style REST custom actions can retain their colon suffixes directly, as in this Google Weather query:

```
https://weather.googleapis.com/v1/currentConditions:lookup
```

### 7. 💾 Save the tool <a href="#step-7-save-tool" id="step-7-save-tool"></a>

Check all settings, scroll to the bottom of the page, and click "<mark style="color:blue;">Confirm</mark>". Your new tool is ready!

## Reference Agent Parameters in Query Parameters <a href="#query-param-templates" id="query-param-templates"></a>

Many third-party APIs use a single query condition string made up of "fixed syntax + a user-provided value", such as the OData-style `$filter=ProductName eq 'Chai'` or the `q=` parameter in search APIs. These APIs need a value embedded in a fixed string rather than a standalone parameter.

Write `{{parameter_name}}` in a "Query Params" value. When the Agent calls the tool, MaiAgent substitutes the value of the parameter with the same name in the "Parameters Schema" before sending the request. The person configuring the tool writes the fixed structure, and the Agent only fills in the value, so the model no longer needs to determine whether the syntax is correct.

### Use case <a href="#query-param-templates-use-case" id="query-param-templates-use-case"></a>

The procurement department wants the company's internal Agent to directly answer "What are the current unit price and stock level for a product?" using the OData query service provided by the company's product catalog system. Previously, each API needed its own custom code for such queries. Now, a procurement specialist only needs to create an API tool, set the query condition to `ProductName eq '{{product_name}}'`, and assign the tool to the Agent. When a colleague asks "What are the unit price and stock level for Chai?" in a conversation, the Agent automatically fills `Chai` into the query condition, calls the API, and replies with the product name, unit price, and stock level.

### Setup steps <a href="#query-param-templates-steps" id="query-param-templates-steps"></a>

The following example uses the public Northwind demo data service (OData). You can follow these steps directly:

{% stepper %}
{% step %}

### Create the tool and enter the basic information <a href="#query-param-step-basic" id="query-param-step-basic"></a>

Follow the “Quickly create an API tool” steps above to add an API tool. Enter a display name (such as <mark style="color:blue;">Product Price Lookup</mark>), the tool name `product_price_lookup`, a description, and a prompt. Set the <mark style="color:blue;">API URL</mark> to:

```
https://services.odata.org/V4/Northwind/Northwind.svc/Products
```

Keep the <mark style="color:blue;">HTTP method</mark> as `GET`.
{% endstep %}

{% step %}

### Declare the parameters the Agent should provide in the parameter schema <a href="#query-param-step-schema" id="query-param-step-schema"></a>

Declare `product_name` in the <mark style="color:blue;">Parameter Schema (JSON Schema)</mark>, and use `description` to tell the Agent what to enter:

```json
{
  "type": "object",
  "properties": {
    "product_name": {
      "type": "string",
      "description": "The full English product name, such as Chai"
    }
  },
  "required": ["product_name"]
}
```

{% endstep %}

{% step %}

### Reference the parameter in a Query parameter value <a href="#query-param-step-template" id="query-param-step-template"></a>

Enter a fixed query template in <mark style="color:blue;">Query Parameters (JSON)</mark>, and use `{{product_name}}` in the value to reference the parameter you just declared:

```json
{
  "$format": "json",
  "$select": "ProductID,ProductName,UnitPrice,UnitsInStock",
  "$filter": "ProductName eq '{{product_name}}'"
}
```

Click “<mark style="color:blue;">Confirm</mark>” to save the tool.
{% endstep %}

{% step %}

### Assign the tool to an Agent and test it <a href="#query-param-step-test" id="query-param-step-test"></a>

Follow [Configure tools for an Agent](/maiagent-user-guide/en/build/tools/configure_tools.md) to add this tool to an Agent whose response mode is Agent mode, then save. Next, open “<mark style="color:blue;">Agent Marketplace</mark>” from the left navigation, switch to “<mark style="color:blue;">Organization-created</mark>”, and select the Agent to start a conversation. Enter “What are the unit price and stock quantity for Chai?” The Agent will display “Tool used” and reply with Chai's unit price and stock quantity.

<figure><img src="https://1360999650-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6v6TNkkOQVfRYfcNirHL%2Fuploads%2Fgit-blob-d301cae503ac598952cb9c0c4ef494c0b8bae727%2Fapi-tool-query-params-chat.png?alt=media" alt="The Agent uses a tool in the conversation and replies with the product name, unit price, and stock quantity"><figcaption><p>The Agent substitutes the product name provided by the user into the query condition, then calls the API</p></figcaption></figure>
{% endstep %}
{% endstepper %}

### Substitution rules <a href="#query-param-templates-rules" id="query-param-templates-rules"></a>

| Rule                                               | Description                                                                                                                                                                                           |
| -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Variable names must match the parameter schema** | `{{product_name}}` corresponds to the parameter name in `properties` in the “Parameter Schema”; the case must match exactly                                                                           |
| **Only values are substituted**                    | Templates apply only to Query parameter values; keys remain unchanged and are not substituted                                                                                                         |
| **Values are inserted as literal text**            | Parameter values are always inserted as literal text without numeric conversion; for example, the leading zero in the business registration number `04595257` is preserved                            |
| **Missing values stop execution**                  | If the Agent does not provide the parameter in this call (or its value is empty), the tool stops with an error identifying the missing parameter, rather than sending `{{product_name}}` unchanged    |
| **Context variables take precedence**              | If a parameter has the same name as a context variable (such as `contact_id` or `conversation_id`), the context variable's value is always used; the value provided by the Agent does not override it |
| **Referenced parameters are also sent separately** | Parameters referenced in templates are still sent as separate query parameters as usual (for example, `product_name=Chai` is also sent); most APIs ignore extra parameters                            |
| **Parameter names are preserved exactly**          | Query parameter keys containing underscores or uppercase letters (such as `Business_Accounting_NO`) are preserved exactly and are not rewritten by the system                                         |

{% hint style="info" %}
Values in “<mark style="color:blue;">Headers (JSON)</mark>” also support `{{parameter_name}}` references to parameters in the parameter schema, using the same rules as Query parameters.
{% endhint %}

{% hint style="warning" %}
Existing tool settings that do not contain `{{ }}` are unaffected. If a Query parameter name in an older tool was rewritten by the system (for example, `Business_Accounting_NO` became `business__accounting_no`), reopen the tool, restore the correct name, and save. When you reopen the editing window, Query parameter values are masked as `****`; saving directly does not lose the original values.
{% endhint %}

## Where to store keys and credentials <a href="#credentials" id="credentials"></a>

API tools do not have a separate secret storage field or secret variables with customizable names. Store the keys needed to call external APIs in the following locations, depending on whose identity the Agent should use:

| Scenario                                                                   | Where to store them                                                                                                                                                                                                  |
| -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The entire organization shares a fixed API Key or Token                    | Enter the actual value directly in the tool's “<mark style="color:blue;">Headers (JSON)</mark>”; if the provider accepts only a query string, enter it in “<mark style="color:blue;">Query Parameters (JSON)</mark>” |
| Each contact uses their own API Key or Token                               | The contact's “<mark style="color:blue;">API Credentials</mark>” tab; see [Use a separate key for each contact](#per-contact-api-credentials)                                                                        |
| Use the identity of the visitor who logged in to Web Chat through Keycloak | The conversation platform's [Call tools using the Keycloak login identity](/maiagent-user-guide/en/build/choose-channel/web-chat.md#keycloak-token-passthrough) setting                                              |
| The service accepts only OAuth login authorization                         | API tools do not provide an OAuth authorization flow. If the service provides an MCP server, use the [OAuth connector for MCP tools](/maiagent-user-guide/en/build/tools/mcp-setup.md#oauth-connector) instead       |

{% hint style="warning" %}
When you paste a cURL command copied from your browser into “<mark style="color:blue;">API URL</mark>”, its headers are also imported into “Headers (JSON)”. They often contain your personal `Cookie` or `Authorization`. These values become fixed credentials shared by all conversations. Delete them before saving, or replace them with a key issued by the provider for this tool.
{% endhint %}

### Supported `{{…}}` substitution variables <a href="#template-variables" id="template-variables"></a>

Values in “Headers (JSON)” and “Query Parameters (JSON)” can use `{{variable_name}}`, which the system substitutes on each call. Only the following names are substituted:

| Variable                              | Substituted value                                                                                                                                                  |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `{{contact_id}}`                      | Contact ID                                                                                                                                                         |
| `{{source_id}}`                       | Source ID                                                                                                                                                          |
| `{{contact_name}}`                    | Contact name                                                                                                                                                       |
| `{{conversation_id}}`                 | Conversation ID                                                                                                                                                    |
| `{{inbox_id}}`                        | Inbox ID                                                                                                                                                           |
| `{{organization_id}}`                 | Organization ID                                                                                                                                                    |
| `{{agent_slug}}`, `{{agent_version}}` | Used by official built-in Agents; always replaced with an empty string when called by organization-created Agents                                                  |
| `{{parameter_name}}`                  | A parameter declared in the “Parameter Schema”, replaced with the value provided by the Agent in this call; see [Substitution rules](#query-param-templates-rules) |

* Variable names are case-sensitive, and there must be no spaces inside the braces; `{{ contact_id }}` is not substituted and is sent unchanged.
* Conversation context variables are replaced with an empty string when no corresponding value exists, such as `{{contact_id}}` when the conversation has no contact.
* Other names (such as a custom key variable name) are not substituted. Saving the tool displays an “<mark style="color:blue;">Contains unknown template variables</mark>” error. If an older tool still uses such syntax, the request sends `{{…}}` unchanged to the other service, causing authentication to fail. Enter the actual key and save again.
* “API URL” and “Parameter Schema” cannot use `{{…}}`.

### Use a separate key for each contact <a href="#per-contact-api-credentials" id="per-contact-api-credentials"></a>

When each contact needs to call an API using their own account (for example, to look up their own orders), include only shared headers in the tool's “Headers (JSON)”, then configure separate credentials for each contact:

1. Open the “<mark style="color:blue;">Contacts</mark>” page and edit the contact (the contact must already be created and saved).
2. Switch to the “<mark style="color:blue;">API Credentials</mark>” tab and click the edit button to the right of the tool.
3. Enter this contact's headers in “<mark style="color:blue;">Headers (JSON format)</mark>”, such as `{"Authorization": "Bearer this contact's Token"}`, then click “<mark style="color:blue;">Save</mark>”.

The procedure is the same as [Configure contact MCP credentials](/maiagent-user-guide/en/build/tools/setup-contacts-mcp-credentials.md). On each call, the system first includes the tool's “Headers (JSON)”, then overrides headers with matching names using the contact's configured headers (the case of the names must match the tool settings). If the contact has no settings, the tool's headers are used. Contact credential values are sent unchanged, without `{{…}}` substitution.

### Who can see these values <a href="#credential-visibility" id="credential-visibility"></a>

* **Tool editing window**: After saving, values in “Headers (JSON)” and “Query Parameters (JSON)” are no longer displayed in plain text, even to the creator. When you reopen the editing window, only the first and last 4 characters of each value are displayed, with `****` in the middle (values of 8 characters or fewer are displayed entirely as `****`). Saving directly does not change the original values. To modify an item, reenter its complete value; items that still contain masked values cannot be saved.
* **AI model**: Header and Query parameter values are not provided to the AI model. The AI model can see only the tool name, prompt (or description), and parameter schema.
* **Tool execution records**: In “<mark style="color:blue;">AgentOps</mark>” → “<mark style="color:blue;">Tool Execution Records</mark>”, “<mark style="color:blue;">Request Information</mark>” shows the actual “<mark style="color:blue;">Request URL</mark>” and “<mark style="color:blue;">Request Headers</mark>” sent for each call:
  * Headers named `Authorization`, `Proxy-Authorization`, `Cookie`, `Set-Cookie`, `X-API-Key`, `Api-Key`, `X-Auth-Token`, or `X-Access-Token` (case-insensitive), as well as headers configured in the contact's “API Credentials”, are displayed as `***` and labeled “<mark style="color:blue;">Masked</mark>”.
  * Headers with other names are displayed in plain text. When the provider allows it, put keys in headers with one of the names listed above.
  * Values configured in “Query Parameters (JSON)” do not appear in the “Request URL”; if an API response or error message echoes these values, they are also replaced with `***`.
  * Content entered directly in “API URL” (including the query string after `?`) is displayed unchanged in the “Request URL”, so do not put keys in the API URL.

{% hint style="info" %}
The httpbin service used for practice includes the request headers it receives unchanged in its response. The response content appears in the conversation and tool execution records. Do not include real keys when testing.
{% endhint %}

## ⚠️ Important reminders <a href="#important-notes" id="important-notes"></a>

**Connection testing**

* After creating a tool, test that the API works correctly
* You can use testing tools to verify the tool's functionality, such as:
  * POSTMAN
  * An API testing request platform built by your organization

**Permission management**

* Regularly review tool usage and permission settings


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.maiagent.ai/maiagent-user-guide/en/build/tools/setup_api_tool.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
