For the complete documentation index, see llms.txt. This page is also available as Markdown.

API Tool Engineering Guide

Connect your REST API to a MaiAgent Agent as a tool: request assembly, authentication, timeouts and retries, error responses to the model, and record lookup.

This page is for engineers who want an Agent to call their own systems: how MaiAgent turns the parameters chosen by the Agent into an HTTP request, how to design your API for model use, and what the model sees when a call fails.

For step-by-step instructions in the admin console (where to add a tool and what to enter in each field), see Create an API Tool in the user manual. This page does not repeat those steps. You can also create and manage tools through the REST API, using the same fields described here. See “Tools and Connectors” in the API documentation.

Call Flow

The Agent only decides which tool to call and which parameters to provide. The platform sends the actual HTTP request. Your API does not need to know anything about the model; it only needs to be an HTTP endpoint accessible from the public internet.

Tool Definition Reference

One API tool corresponds to one endpoint and one HTTP method. The platform currently does not import OpenAPI documents. If your API has an OpenAPI specification, create a separate tool for each operation you want to expose to the Agent, then combine the path parameter, query, and requestBody schemas and paste them into “Parameter Schema.”

For field values, format restrictions, and locations in the interface, refer to Create an API Tool: Detailed API Configuration in the user manual. Engineers integrating the API should also know the following:

  • The tool's name is the identifier the model uses to call it. Before it is sent to the model, it is normalized to match ^[a-zA-Z][a-zA-Z0-9_]*$, with a maximum of 64 characters. Hyphens become underscores; names that exceed the limit are truncated and given a hash suffix. Use snake_case from the start, such as get_order_status.

  • The model decides when to call a tool based only on its description. If prompt has a value, it is used; otherwise, description is used. Clearly describe what the tool does, when to use it, and what it returns.

  • Field names when creating a tool through the REST API: API URL is apiUrl, HTTP method is httpMethod (get, post, put, patch, delete), headers are rawHeaders, Query parameters are rawQueryParams, parameter schema is rawParametersSchema, and display name is displayName.

Parameter Schema (JSON Schema)

The platform converts the parameter schema into the model's function-calling schema, then validates the parameters returned by the model against it.

Rules and limitations:

  • The top level must be type: "object". Supported features include properties, required, default, enum, nested object, and array.

  • Parameter names may contain only English letters, digits, underscores, dots, hyphens, and Chinese characters, and must be 1–64 characters long. Invalid names are rejected when the tool is saved.

  • The platform supplies default values: if the model does not provide a parameter, the platform fills in its default before sending the request. To always send a fixed value without leaving it to the model, use default or enter it directly in Query parameters.

  • Write a description for every parameter. The quality of the parameters supplied by the model depends almost entirely on this text. A format example (“in a format such as A123456”) is much more effective than specifying only the type.

  • The parameter name timeout is reserved: if the model provides it, the platform uses it as the timeout in seconds for this request and does not send it to your API. Do not use this name for a business parameter.

  • The model's function calling is responsible for honoring required and types. When saving a tool, the platform only checks that the parameter schema itself is valid JSON Schema. Before sending a request, it only checks that all path parameters are present. The model may still occasionally omit required parameters. Have your API return 400 and explain which field is missing; the model can then fill in the parameters again and call the tool (see How Responses Reach the Model).

  • Parameter schema changes take effect immediately: the tool definition is read when processing begins for each message. The next message after saving uses the new schema, including in an ongoing conversation; you do not need to attach the tool again. For MCP tools, however, the “Allowed Tools” list is a snapshot retrieved when the tool is saved. Retrieve it again after adding tools on the server. See Create an MCP Tool in the user manual.

Request Assembly

Each parameter in the parameter schema can specify a location (the JSON Schema property's location: path, query, body, or header). The platform places the value supplied by the model in that part of the request. If no location is specified, the HTTP method determines where it goes:

Method
Parameters Without a Specified Location
Body

GET

Placed in the query string

Sent only when parameters are explicitly assigned to body

POST, PUT, PATCH

Placed in the JSON body (Content-Type: application/json)

Always sends a JSON object

DELETE

Not sent; specify a location to pass a value

Sent only when parameters are explicitly assigned to body

Key points:

  • Path parameters: use single braces {parameter_name} in the API URL, such as https://api.example.com/orders/{order_id}, and set the parameter location to path. Values are URL-encoded before substitution. If any path parameter value is missing for a call, the platform does not send the request and reports an error directly. For rules and interface instructions, see Path Parameters and Parameter Locations in the user manual.

  • Configured Query parameters take precedence over model parameters with the same name: if a configured “Query parameter” has the same name as a model parameter, the configured value is used. Put keys that must be sent in the query string in Query parameters so the model cannot override them.

  • Configured headers take precedence over parameters with the same name: parameters with location header are sent as headers using their parameter names. If the tool's “Headers” or contact credentials already contain a header with the same name (case-insensitive), the configured value is used.

  • The body is always a JSON object. form-data, file uploads, and XML are not supported. If your API requires these formats, provide a JSON interface on your side.

{{variables}} in Headers and Query Parameters

Header and Query parameter values can reference conversation context variables ({{contact_id}}, {{source_id}}, {{conversation_id}}, etc.) and parameters declared in the parameter schema using {{parameter_name}}. The platform substitutes them on each call. For available variables and substitution rules, see Substituted {{…}} Variables in the user manual.

{{source_id}} is the variable ISVs use most often. It is the contact's external ID—the sourceId you provide when embedding Web Chat or synchronizing contacts. Your system recognizes its own user IDs. Put this ID in a header (for example, X-User-Id: {{source_id}}) or the query string so your API can query data as that user, without asking the model to “guess” who the user is through the parameter schema.

Authentication

Three methods can be used together, in order of precedence from lowest to highest:

  1. Fixed tool-level credentials: enter Authorization: Bearer ... or X-API-Key: ... in headers, or enter a key in Query parameters. Calls to your API represent the “entire organization.” After saving, values are masked with **** in the admin console. Query parameter values in tool execution records and API request records are also masked.

  2. Context variables: as described above, use {{source_id}} and similar variables to tell your API “who is asking,” and handle authorization on your side. Credentials remain at the tool level.

  3. Contact-level credentials (API Credential): bind a set of headers to a specific contact. On a call, they override tool-level headers with the same names. This suits cases where each end user has their own token (your system needs to make calls as the user, rather than as an integration account).

Your backend writes contact-level credentials after the user logs in:

Sending credentials again for the same contact and tool updates the existing credentials; call the endpoint again when the token expires. Credentials apply only in “that contact's conversations.” Other contacts calling the same tool still use tool-level credentials.

Tokens are usually written to contact credentials during identity synchronization when embedding Web Chat. See Contact Identity Synchronization and Token Updates.

Where to Put Keys and Who Can See Them

The platform has no “secret variable” mechanism. Custom names such as {{SECRET_XXX}} are not substituted and are rejected when saving a tool. Enter keys directly in the tool's headers or Query parameters, or write them to contact-level credentials. The only substitutable {{variables}} are the context variables and parameter names listed in the previous section.

Location
Masking Rules

Tool editing screen

After saving, header and Query parameter values show only their first and last 4 characters, with **** in between. Values of 8 characters or fewer are displayed entirely as ****

Model context

Header and Query parameter values are not provided to the model. The model sees only the tool name, description, and parameter schema

requestHeaders in tool execution records

Values are displayed as *** for headers whose names match the platform's sensitive header list, and for all headers from contact-level credentials. Name matching is case-insensitive

Request URL and response in tool execution records

Values configured in the tool's “Query parameters” do not appear in the request URL. If a response or error message echoes these values, they are also replaced with ***

The platform's sensitive header list is Authorization, Proxy-Authorization, Cookie, Set-Cookie, X-API-Key, Api-Key, X-Auth-Token, and X-Access-Token. Custom headers with other names (such as X-Partner-Secret) appear in plain text in tool execution records. Therefore:

  • If you can choose the header name, put keys in a header from the list above.

  • If you must use a custom header name (such as x-functions-key), set sensitiveHeaders on the tool through the REST API: an array of header names, with at most 50 entries, each up to 256 characters long. Matching is case-insensitive. Only API tools accept this field, and it is not available in the admin console's tool settings. Once configured, masking also applies when viewing existing execution records. When reading a tool, the read-only globalSensitiveHeaders field returns the platform's current sensitive header list.

  • Organization administrators cannot modify the platform list. On-premises deployments can replace the entire list using the TOOL_API_SENSITIVE_HEADERS environment variable.

  • Do not put keys in the API URL. The URL (including the query string after ?) appears unchanged in tool execution records.

For the corresponding explanation in the interface, see Who Can See These Values in the user manual.

Passing Conversation Attachments to Tools

API tools can access files uploaded by users in conversations by passing URLs. The platform does not put file contents in the request. Instead, the model fills a parameter you declare with the attachment's download URL, and your API downloads it.

How it works:

  1. After a user uploads files, the model sees each attachment's id, filename, and file (download URL). Image attachments also include a filename and URL.

  2. Declare a string parameter in the parameter schema to receive the URL. When calling the tool, the model fills it with the corresponding attachment's URL.

  3. Your API downloads the URL with GET.

Key points:

  • URL format: file is a stable platform URL (https://<API domain>/api/media/...) that redirects to a currently valid signed storage URL on each download. Your download code must follow HTTP redirects. Downloading from this URL does not require an API key.

  • The platform corrects URLs rewritten by the model: when copying a URL, the model may occasionally get the host or protocol wrong. If a URL in a parameter value can be matched to an attachment in this conversation, the platform replaces it with the correct URL before sending the request. URLs that do not match any attachment are sent unchanged.

  • Multiple files in one call: declare the parameter as an array of strings ("type": "array", "items": {"type": "string"}) and explain in description that each element is an attachment URL.

  • Requests are still JSON: the body does not support form-data or binary uploads (see Request Assembly), so the platform cannot send “the file itself” to your API.

  • Size and format: allowed file types and per-file size limits depend on the conversation platform's attachment settings. See API Conventions: Upload Size Limits. Your API should check Content-Length and file type itself.

  • Retention: conversation attachments have a retention period. Files are deleted and URLs stop working after it expires. If you need to keep a file long term, download it to your own storage when the tool is called. For retention rules, see Credits Billing: Conversation Attachment Storage in the user manual.

  • Parameter types: parameters support string, number, integer, boolean, enum, nested object, and array (see Parameter Schema). There is no dedicated “file” type; files are always passed as URL strings.

Timeouts, Retries, and TLS

Item
Behavior

Timeout

The default timeout for each HTTP request is 30 seconds (a platform-level setting, configurable on-premises). It is not the total time limit for the entire tool call. Calls that time out are recorded as timeout, and the model receives “API request timed out.”

Retries

Up to 3 retries after the initial request, for a maximum of 4 attempts, with backoff delays of 1, 2, and 4 seconds. Request errors, including timeouts, and 408, 409, 429, 500, 502, 503, and 504 are retried. Other 4xx responses are not retried.

TLS

The certificate chain and hostname are always verified. If the connection fails because your certificate chain uses an older root certificate without a Subject Key Identifier (some local CAs), only MaiAgent can enable this exception in system administration, per tool or per domain. This option is not available in the admin console's tool settings; contact MaiAgent. Self-signed certificates are not supported.

What this means for your API:

  • Write endpoints must be idempotent. Retries can send the same POST twice. Deduplicate using a business key in the parameters (order number or external ID), or return 409 so platform retries still refer to the same record.

  • The entire tool call accumulates the time spent on all requests and backoff delays. Repeated timeouts may take more than 120 seconds, so 30 seconds is not the total upper limit on the model's wait. Keep query endpoints within a few seconds. For long-running work, use “create task → return task ID” and provide a separate query tool.

  • Returning Retry-After with 429 has no effect; the platform uses fixed backoff. Estimate rate limits assuming 3 retries.

How Responses Reach the Model

The model sees your raw response body, without structural parsing:

Situation
What the Model Sees

2xx

Raw body (response.text). An empty body becomes the string None.

Non-2xx (still unsuccessful after retries)

A message starting with API request failed, followed by HTTP <status code>: <raw body>.

Timeout

A message starting with API request timed out, followed by an error description.

Connection error, DNS, or TLS failure

A message starting with API request failed, followed by the exception message.

Insufficient organization Credits

The call is not sent, and the model receives an explanation that the balance is insufficient.

If the response exceeds a certain proportion of the model's context window (80% by default), the platform retains the beginning and end, and adds a “truncated” notice at the start. The middle is removed.

API design recommendations:

  • Return concise JSON. Return only the fields the model needs, rather than an entire ORM object. Limit each list response to a few dozen records; provide pagination parameters so the model can query additional records.

  • Use readable error messages, rather than error codes alone. {"error": "order_id A123 does not exist; please check the number"} helps the model correct parameters or explain the issue to the user better than {"code": 40401}.

  • 4xx responses provide feedback to the model: for missing or malformed parameters, return 400 and identify the field so the model can try supplying parameters again. Do not wrap errors in 200 responses; the model will summarize them for the user as successful results.

  • If a response echoes the query string (as some frameworks' error pages do), the platform masks the configured Query parameter values before passing the response to the model. Headers stay out of the body only if your API does not print them there.

  • To let the model tell the user “no data found,” explicitly return 404 with an explanation, rather than 200 with an empty array.

  • Image URLs in responses: when your API returns an image URL, the model includes it in its reply using Markdown image syntax (![Description](https://…)). When Web Chat displays it, the user's browser fetches the image directly from that URL. These are two independent requests: platform → your API (with tool headers and credentials), and browser → image URL (without any tool headers). The image URL must therefore be publicly accessible without authentication and remain valid throughout the conversation. When a short-lived signed URL (such as Azure SAS) expires, images in older messages fail to display. See Creating Conversations and Messages: Images in Message Content.

Records and Debugging

Every call writes a tool execution record. Find these in the admin console under “AgentOps → Tool Execution Records,” or query them through the API:

Available filters: tool, tool_type=api, status (success, failure, pending, timeout), chatbot, start_date, end_date, and query (full text). Each record contains:

  • The input parameters supplied by the model, inputParameters, and the actual requestMethod, requestHeaders (sensitive values masked), and requestBody sent by the platform.

  • The raw response, outputResult (after truncation), or errorMessage.

  • Execution time and status, plus the associated message and Agent.

To read this API, members need the AgentOps “Tool Execution Records” permission. Organization owners are exempt from this restriction.

Suggested debugging order:

  1. Check whether requestHeaders and requestBody in the record have the expected structure. A {{variable}} that was not substituted usually indicates a misspelled variable name or a missing parameter with that name in the parameter schema.

  2. If errorMessage starts with HTTP <code>, your API returned the error. The raw body follows it.

  3. If status=timeout but your logs show a response was sent, the response took more than 30 seconds. Check your p95 first.

  4. If the model “does not call the tool,” no record is created. In this case, adjust the tool description and parameter description, rather than the API.

Billing

Each API tool call that is successfully sent incurs one “API Tool Call” Credits charge. Calls are not sent when Credits are insufficient. Retries for failed or timed-out calls are not charged separately. Specific prices depend on the organization's plan; see the Credits explanation in the user manual.

Pre-launch Checklist

Last updated

Was this helpful?