h2oGPTe REST API: OpenAPI specification file
Overview​
The h2oGPTe OpenAPI specification file outlines the structure and functionality of the h2oGPTe REST API, including endpoints, request and response formats, and authentication requirements.
What you will learn​
- How to generate client SDKs (Python, JavaScript, Go) from the spec using the OpenAPI Generator CLI.
- How to configure authentication and data deletion for REST API integrations.
- How to use the OpenAI-compatible REST endpoints with existing OpenAI-based clients.
- How to register and manage custom tools that extend agents with MCP servers, browser actions, or general-purpose code.
- How to register and manage custom agents programmatically using the Python SDK.
Helpful resources​
-
OpenAPI specification (YAML) — canonical spec used by SDK generators and tools:
-
Interactive documentation — explore and try REST endpoints with live requests:
How we generated the SDKs​
The available SDKs were developed using the OpenAPI Generator CLI, a robust tool designed to create client libraries directly from OpenAPI specifications.
Installation​
pip install openapi-generator-cli==7.10.0
SDK Setup Guide​
Python
JavaScript
Go
General CLI structure​
openapi-generator-cli generate \
-i rest_api_spec_h2ogpte.yaml \
-g python \
-o sdk \
--additional-properties=packageName=h2ogpte_rest_client,packageVersion=1.6.2,projectName=h2ogpte-rest-client
Prerequisites​
-
Create a folder for your Python SDK. Paste the following commands in your terminal:
mkdir python-sdk
cd python-sdk -
Download the OpenAPI specification file: Download api-spec.yaml and move it to the python-sdk folder.
-
Set up a Python environment with Python 3.8 or later:
python3 -m venv venv
source venv/bin/activate
pip install openapi-generator-cli==7.10.0
Generate SDK​
In the python-sdk directory, run the following command (CLI) to create the Python SDK using the OpenAPI Generator CLI:
openapi-generator-cli generate \
-i rest_api_spec_h2ogpte.yaml \
-g python \
-o sdk \
--additional-properties=packageName=h2ogpte_rest_client,packageVersion=1.6.2,projectName=h2ogpte-rest-client
The CLI creates a folder named sdk containing the Python SDK.
Install Dependencies​
-
Navigate to the SDK directory and install dependencies:
cd sdk
pip install -r requirements.txt -
Install the Python SDK:
pip install setuptools
python setup.py install
Test SDK with Collection Creation​
Create a test Collection to verify the Python SDK installation:
# This example with the Python SDK creates a new Collection with the following
# name and description (while testing whether the Python SDK was properly installed):
# Name = The name of my Collection
# Description = The description of my Collection
import h2ogpte_rest_client
import os
from h2ogpte_rest_client.rest import ApiException
from pprint import pprint
configuration = h2ogpte_rest_client.Configuration(
# This line specifies the URL where Enterprise h2oGPTe is hosted.
# The address should be the location where the API key was created.
host="https://h2ogpte.genai.h2o.ai/",
# This line specifies the API key for authentication.
access_token=os.environ["BEARER_TOKEN"]
)
with h2ogpte_rest_client.ApiClient(configuration) as api_client:
api_instance = h2ogpte_rest_client.CollectionsApi(api_client)
collection_create_request = h2ogpte_rest_client.CollectionCreateRequest(
name="The name of my Collection",
description="The description of my Collection"
)
try:
api_response = api_instance.create_collection(collection_create_request)
print("The response of CollectionsApi->create_collection:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling CollectionsApi->create_collection: %s\n" % e)
Set up authentication:
Before you can run the Python script, you need to export a global API key within the sdk directory:
export BEARER_TOKEN="sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Run the test:
Within the sdk directory, run the following command:
python3 create_a_collection.py
Expected output:
The response of CollectionsApi->create_collection:
Collection(id='091c6ab1-a031-4eb7-9e3e-7d0939911d00', name='The name of my Collection', description='The description of my Collection', embedding_model='BAAI/bge-large-en-v1.5', document_count=0, document_size=0, updated_at=datetime.datetime(2024, 12, 3, 21, 39, 49, 442087, tzinfo=TzInfo(UTC)), user_count=0, is_public=False, username='sergio.perez@h2o.ai', sessions_count=0)
General CLI structure​
openapi-generator-cli generate \
-i rest_api_spec_h2ogpte.yaml \
-g javascript \
-o sdk \
--additional-properties=packageName=h2ogpte-rest-client,packageVersion=1.6.2,projectName=h2ogpte-rest-client,npmName=h2ogpte-rest-client,npmVersion=h2ogpte-rest-client
Prerequisites​
-
Create a folder for your JavaScript SDK. Paste the following commands in your terminal:
mkdir javascript-sdk
cd javascript-sdk -
Download the OpenAPI specification file: Download api-spec.yaml and move it to the javascript-sdk folder.
-
Set up a Python environment (needed for OpenAPI Generator CLI):
python3 -m venv venv
source venv/bin/activate
pip install openapi-generator-cli==7.10.0
Generate SDK​
In the javascript-sdk directory, run the following command (CLI) to create the JavaScript SDK using the OpenAPI Generator CLI:
openapi-generator-cli generate \
-i rest_api_spec_h2ogpte.yaml \
-g javascript \
-o sdk \
--additional-properties=packageName=h2ogpte-rest-client,packageVersion=1.6.2,projectName=h2ogpte-rest-client,npmName=h2ogpte-rest-client,npmVersion=h2ogpte-rest-client
The CLI creates a folder named sdk containing the JavaScript SDK.
Install Dependencies​
-
Install the SDK dependencies:
cd sdk
npm install -
Link the library globally in npm:
npm link -
Create a Node.js project to test the SDK:
cd ..
mkdir my-javascript-sdk-project
cd my-javascript-sdk-project
npm init -y -
Link the SDK to your project:
npm link /path/to/<THE_SDK_FOLDER> -
Build the SDK module:
cd ../sdk
npm run build
Test SDK with Collection Creation​
Create a test Collection to verify the JavaScript SDK installation:
// This example with the JavaScript SDK creates a new Collection with the following
// name and description (while testing whether the SDK was properly installed):
// Name = The name of my Collection
// Description = The description of my Collection
import H2ogpteRestClient from 'h2ogpte-rest-client';
let defaultClient = H2ogpteRestClient.ApiClient.instance;
let bearerAuth = defaultClient.authentications['bearerAuth'];
// The access token should be a global API key.
bearerAuth.accessToken = "sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
let apiInstance = new H2ogpteRestClient.CollectionsApi();
let collectionCreateRequest = new H2ogpteRestClient.CollectionCreateRequest(
"The name of my Collection", // name parameter
"The description of my Collection" // description parameter
);
apiInstance.createCollection(collectionCreateRequest, (error, data, response) => {
if (error) {
console.error(error);
} else {
console.log('API called successfully. Returned data: ' + data);
}
});
Run the test:
node create-a-collection.mjs
General CLI structure​
openapi-generator-cli generate \
-i rest_api_spec_h2ogpte.yaml \
-g go \
-o h2ogpte_rest_client \
--additional-properties=packageName=h2ogpte_rest_client,packageVersion=1.6.2,projectName=h2ogpte_rest_client,goModuleName=h2ogpte_rest_client,isGoSubmodule=true
Prerequisites​
-
Create a Go project. Paste the following commands in your terminal:
mkdir my-project
cd my-project
go mod init my-project -
Download the OpenAPI specification file: Download api-spec.yaml and move it to the my-project folder.
-
Set up a Python environment (needed for OpenAPI Generator CLI):
python3 -m venv venv
source venv/bin/activate
pip install openapi-generator-cli==7.10.0
Generate SDK​
In the go-sdk directory, run the following command (CLI) to create the Go SDK using the OpenAPI Generator CLI:
openapi-generator-cli generate \
-i rest_api_spec_h2ogpte.yaml \
-g go \
-o h2ogpte_rest_client \
--additional-properties=packageName=h2ogpte_rest_client,packageVersion=1.6.2,projectName=h2ogpte_rest_client,goModuleName=h2ogpte_rest_client,isGoSubmodule=true
Install Dependencies​
Create a work file to add the SDK module:
go work init
go work use ./h2ogpte_rest_client
Test SDK with Collection Creation​
Create a test Collection to verify the Go SDK installation:
package main
import (
"context"
"fmt"
"os"
openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/h2ogpte_rest_client"
)
func main() {
collectionCreateRequest := *openapiclient.NewCollectionCreateRequest("The name of my Collection", "The description of my Collection") // CollectionCreateRequest |
configuration := openapiclient.NewConfiguration()
configuration.AddDefaultHeader("Authorization","Bearer sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
apiClient := openapiclient.NewAPIClient(configuration)
resp, r, err := apiClient.CollectionsAPI.CreateCollection(context.Background()).CollectionCreateRequest(collectionCreateRequest).Execute()
if err != nil {
fmt.Fprintf(os.Stderr, "Error when calling `CollectionsAPI.CreateCollection``: %v\n", err)
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
}
// response from `CreateCollection`: Collection
fmt.Fprintf(os.Stdout, "Response from `CollectionsAPI.CreateCollection`: %v\n", resp)
}
Run the test:
go run create_a_collection.go
Expected output:
Response from `CollectionsAPI.CreateCollection`: &{e6926802-9529-419f-9ddd-cbb262137a8a The name of my Collection The description of my Collection BAAI/bge-large-en-v1.5 0 0 2024-12-11 23:43:19.972726 +0000 UTC 0 false sergio.perez@h2o.ai 0 <nil>}
CLI Parameters​
-i: The path or URL to the OpenAPI spec (for example,openapi.yamlorhttps://example.com/openapi.yaml).-g: The target programming language for the client (for example,python,javascript,go).-o: The output directory for the generated files (for example,./python-client).--additional-properties: Additional settings for client generation (for example,usePromises=truefor JavaScript).
For more information about generating SDKs in other languages, visit the OpenAPI Generator CLI documentation.
Authentication​
- The value exported for the
BEARER_TOKEN(Python),accessToken(JavaScript), orAuthorizationheader (Go) should be a global API key. - To learn more about what is a global API key and how to create one, see APIs.
- All URIs are relative to https://h2ogpte.genai.h2o.ai/. The global API key must be created on this platform to ensure successful requests.
- Make sure to replace
sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXwith your actual API key.
Delete your data​
To see the detailed process for deleting your data, refer to the User data deletion documentation.
OpenAI-compatible REST API​
This API provides OpenAI-style endpoints for chat completions, chat responses, and model listing for integration with OpenAI-based applications.
Endpoints​
POST /openai_api/v1/chat/completions : OpenAI-compatible chat completions endpoint.
POST /openai_api/v1/responses : OpenAI-compatible responses endpoint for new chat interactions.
GET /openai_api/v1/models : Lists available models for use with chat and completions endpoints.
Authentication​
Use the same API key authentication as the main REST API:
Authorization: Bearer sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Make sure to replace sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX with your actual API key.
Chat completions​
Endpoint: POST /openai_api/v1/chat/completions
Supported features: developer, system, user, and assistant message types with text and image content parts are accepted as input for user messages. See OpenAI API reference for complete feature comparison.
API behavior​
The following table shows the key differences from using OpenAI API:
| Feature | Support |
|---|---|
| Message types | Only developer, system, user, and assistant messages are supported |
| Content parts | Only text and image content parts are supported in user messages (audio and file content are not supported) |
| Agentic features | Tool calls, function calling, and other agentic features are not supported |
| Collections | Document collections are not supported |
Most unsupported fields are ignored without error.
Request:
{
"model": "auto",
"messages": [
{ "role": "user", "content": "What color is the sky?" }
],
"temperature": 0.7,
"max_tokens": 1024
}
Response:
{
"choices": [
{
"message": { "role": "assistant", "content": "The sky is typically blue during the day." },
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 9,
"completion_tokens": 12,
"total_tokens": 21
}
}
Responses​
Endpoint: POST /openai_api/v1/responses
Supported features: Only text input is accepted. For a full list of OpenAI API capabilities, see the OpenAI API reference.
API behavior​
The following table shows the key differences from using OpenAI API:
| Feature | Support |
|---|---|
| Input types | Only text content is supported in the input parameter (no files, images, or base64 content) |
| Agentic features | Tool calls, function calling, and other agentic features are not supported |
| Collections | Document collections are not supported |
Most unsupported fields are ignored without error.
Request:
{
"model": "auto",
"input": "What color is the sky?",
"instructions": "You are a helpful assistant.",
"temperature": 0.7,
"stream": false
}
Alternative Request with Chat History:
{
"model": "auto",
"input": [
{ "role": "user", "content": "What color is the sky?" },
{ "role": "assistant", "content": "The sky is blue." },
{ "role": "user", "content": "What was the answer, again?" }
],
"stream": true
}
Response:
{
"id": "resp_abc123",
"object": "response",
"created_at": 1677610602,
"model": "auto",
"status": "completed",
"output": [
{
"id": "msg_123",
"role": "assistant",
"status": "completed",
"type": "message",
"content": [
{
"type": "output_text",
"text": "The sky is typically blue during the day.",
"annotations": []
}
]
}
],
"error": null
}
List models​
Endpoint: GET /openai_api/v1/models
See OpenAI API reference for full OpenAI API capabilities.
Request:
GET /openai_api/v1/models
Authorization: Bearer sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Response:
{
"object": "list",
"data": [
{
"id": "gpt-3.5-turbo",
"object": "model",
"created": 1677610602,
"owned_by": "h2oai",
"permission": [
{
"id": "modelperm-abc123",
"object": "model_permission",
"created": 1677610602,
"allow_create_engine": false,
"allow_sampling": true,
"allow_logprobs": false,
"allow_search_indices": false,
"allow_view": true,
"allow_fine_tuning": false,
"organization": "*",
"group": null,
"is_blocking": false
}
],
"root": "gpt-3.5-turbo",
"parent": null
}
// ... more models may be listed here
]
}
Compatibility​
- OpenAI Python client: Compatible with basic chat completions, responses, and model listing endpoints. You can use the standard OpenAI Python library with these specific endpoints.
- Cline VSCode extension: Supported with the OpenAI Compatible provider setting.
- Streaming: Supported via the
stream=trueparameter (responses are streamed as per OpenAI's API).
Custom Tools API​
Custom tools extend h2oGPTe agents with additional capabilities such as remote MCP servers, local MCP servers, browser automation actions, and general-purpose code execution. Use this API to programmatically register custom tools that agents can invoke during conversations.
Authentication​
Use the same API key authentication as the main REST API. The caller must have the ConfigureAgents permission, or the API returns 401 Unauthorized.
Authorization: Bearer sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Make sure to replace sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX with your actual API key.
Add a custom agent tool​
Endpoint: POST /api/v1/agents/custom_tools
Create a custom agent tool by uploading tool files and providing configuration. The request uses multipart/form-data encoding.
Parameters​
| Parameter | Type | Required | Description |
|---|---|---|---|
tool_type | string | Yes | Type of custom tool (see values below) |
tool_args | JSON string | Yes | Tool-specific arguments (structure varies by tool_type) |
file | binary | Conditional | Tool file to upload. Required for local_mcp, browser_action, and general_code. Optional for remote_mcp. |
filename | string | No | Override filename for the uploaded file |
tool_type values:
| Value | Description | File requirements |
|---|---|---|
local_mcp | Model Context Protocol server running locally | .zip file containing MCP server code |
remote_mcp | Model Context Protocol server running remotely | Optional .json file with MCP configuration |
browser_action | Custom browser automation actions | .py file (must start with browser_) or .zip |
general_code | General-purpose code execution | .py or .zip file with custom code |
tool_args structure:
For remote_mcp:
{
"mcp_config_json": "{\"mcpServers\": {\"my-server\": {\"url\": \"https://example.com/mcp\"}}}",
"enable_by_default": true
}
To control which agent roles can use a remote MCP tool, include "tool_usage_mode" inside the mcp_config_json string (at the top level, alongside "mcpServers").
For local_mcp:
{
"tool_name": "my_mcp_server",
"description": "A local MCP server for data retrieval",
"enable_by_default": true,
"tool_usage_mode": ["runner", "creator"]
}
For browser_action:
{
"tool_name": "browser_scraper",
"description": "Scrape structured data from web pages",
"enable_by_default": true,
"tool_usage_mode": ["runner", "creator"]
}
For general_code:
{
"tool_name": "my_tool",
"description": "My custom tool",
"enable_by_default": true,
"should_unzip": false,
"tool_usage_mode": ["runner", "creator"]
}
| Field | Type | Required | Description |
|---|---|---|---|
mcp_config_json | string | Yes (remote_mcp only) | JSON-encoded string with MCP server configuration |
tool_name | string | No | Defaults to filename without extension |
description | string | No | Tool description |
enable_by_default | boolean | No | Whether the tool is enabled by default. Defaults to true |
should_unzip | boolean | No | For general_code .zip files only |
tool_usage_mode | string[] | No | Agent roles that can use this tool. Applies to local_mcp, browser_action, and general_code as a top-level field. For remote_mcp, include inside mcp_config_json. Defaults to ["runner", "creator"] |
Python SDK example​
from h2ogpte import H2OGPTE
client = H2OGPTE(address="https://h2ogpte.genai.h2o.ai", api_key="sk-XXXXX...")
# Add a remote MCP tool
tool_ids = client.add_custom_agent_tool(
tool_type="remote_mcp",
tool_args={
"mcp_config_json": '{"mcpServers": {"my-server": {"url": "https://example.com/mcp"}}}',
"enable_by_default": True,
},
)
# Add a general code tool with file upload
tool_ids = client.add_custom_agent_tool(
tool_type="general_code",
tool_args={
"tool_name": "my_tool",
"description": "A custom code tool",
"enable_by_default": True,
},
custom_tool_path="/path/to/my_tool.py",
)
cURL example​
# Add a remote MCP tool
curl -X POST "https://h2ogpte.genai.h2o.ai/api/v1/agents/custom_tools" \
-H "Authorization: Bearer sk-XXXXX..." \
-F "tool_type=remote_mcp" \
-F 'tool_args={"mcp_config_json": "{\"mcpServers\": {\"my-server\": {\"url\": \"https://example.com/mcp\"}}}", "enable_by_default": true}'
# Add a general code tool with file upload
curl -X POST "https://h2ogpte.genai.h2o.ai/api/v1/agents/custom_tools" \
-H "Authorization: Bearer sk-XXXXX..." \
-F "tool_type=general_code" \
-F 'tool_args={"tool_name": "my_tool", "description": "A custom code tool", "enable_by_default": true}' \
-F "file=@/path/to/my_tool.py" \
-F "filename=my_tool.py"
Response​
Success — 201 Created
Returns a JSON array of created tool objects:
[
{
"agent_custom_tool_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
]
For remote_mcp tools with multiple servers defined in mcpServers, the response contains one entry per server.
Error responses
| Status | Message | Cause |
|---|---|---|
| 400 | "Failed to parse form data." | Request body is not valid multipart/form-data |
| 400 | "tool_type is required." | Missing tool_type form field |
| 400 | "Invalid JSON format for tool_args." | tool_args is not valid JSON |
| 400 | "The request does not contain a file." | File is required but not provided (applies to local_mcp, browser_action, general_code) |
| 401 | "Unauthorized" | Missing or invalid API key, or the user lacks ConfigureAgents permission |
| 415 | "Invalid file extension: {ext}. Allowed extensions are .zip." | Wrong file type for local_mcp |
| 415 | "Invalid file extension: {ext}. Allowed extensions are .zip, .py." | Wrong file type for browser_action or general_code |
| 415 | "Invalid file extension: {ext}. For remote_mcp, allowed extensions are .json." | Wrong file type for remote_mcp |
| 413 | "File is too large, maximum size is 20MB" | Uploaded file exceeds the 20 MB size limit |
Error response body format:
{
"code": 400,
"message": "tool_type is required."
}
Inspect an MCP tool​
Endpoint: POST /api/v1/agents/mcp/inspect_tool
Discover the sub-tools an MCP server provides. This endpoint supports three inspection modes—provide exactly one:
| Parameter | Type | Required | Description |
|---|---|---|---|
tool_id | string | One of three | ID of an existing MCP tool to inspect (resolves stored env vars server-side) |
servers | object | One of three | Dict mapping server names to config dicts for pre-add inspection |
file_name | string | One of three | Filename of the MCP package to inspect (used with file_data_base64) |
file_data_base64 | string | Conditional | Base64-encoded file content (required when file_name is provided) |
model | string | No | LLM model for optional security inspection |
Response​
Returns a unified result envelope:
{
"status": "success",
"servers": [
{
"server_name": "my-server",
"server_type": "stdio",
"tools": [
{"name": "tool_name", "description": "...", "parameters": {...}}
],
"tool_count": 3
}
]
}
| Field | Type | Description |
|---|---|---|
status | string | "success" or "error" |
servers | array | List of per-server inspection results |
error | string | Top-level error message (present when status is "error") |
Each server object in the servers array contains:
| Field | Type | Description |
|---|---|---|
server_name | string | Name of the inspected server |
server_type | string | Detected server framework or transport protocol (for example, stdio, http, sse, fastmcp) |
tools | array | List of tool objects with name, description, and parameters |
tool_count | integer | Number of tools after filtering |
status | string | Per-server status |
error | string | Per-server error message |
detection_method | string | How tools were detected |
The response may include fields beyond those documented here. You can safely ignore them.
Python SDK example​
from h2ogpte import H2OGPTE
client = H2OGPTE(address="https://h2ogpte.genai.h2o.ai", api_key="sk-XXXXX...")
# Inspect an existing tool by ID
result = client.inspect_mcp_tool(tool_id="<tool-id>")
for srv in result["servers"]:
print(f"{srv['server_name']}: {srv['tool_count']} tools")
# Inspect a remote config before adding
result = client.inspect_mcp_tool(
servers={"playwright": {"command": "npx", "args": ["@playwright/mcp@latest"]}}
)
# Inspect a local MCP package file
result = client.inspect_mcp_tool(file_path="/path/to/my_mcp_tool.zip")
cURL example​
# Inspect by tool ID
curl -X POST "https://h2ogpte.genai.h2o.ai/api/v1/agents/mcp/inspect_tool" \
-H "Authorization: Bearer sk-XXXXX..." \
-H "Content-Type: application/json" \
-d '{"tool_id": "<tool-id>"}'
# Inspect a remote server config
curl -X POST "https://h2ogpte.genai.h2o.ai/api/v1/agents/mcp/inspect_tool" \
-H "Authorization: Bearer sk-XXXXX..." \
-H "Content-Type: application/json" \
-d '{"servers": {"my-server": {"command": "npx", "args": ["@my/mcp-server"]}}}'
Error responses​
| Status | Message | Cause |
|---|---|---|
| 400 | "Invalid format for the request body." | Missing or invalid request body |
| 401 | "Unauthorized" | Missing or invalid API key, or user lacks ConfigureAgents permission |
| 500 | "Failed to inspect MCP tool." | MCP server timed out or failed to start |
When inspecting by tool_id, the backend resolves os.environ/ references from the tool's stored agent key associations. No secrets are returned in the response.
Other custom tool operations​
In addition to creating tools, you can list, update, and delete custom tools that belong to the current user.
List custom tools​
Endpoint: GET /api/v1/agents/custom_tools
Returns a JSON array of custom tool objects for the authenticated user.
Example response:
[
{
"id": "uuid-string",
"tool_name": "my_tool",
"tool_type": "general_code",
"tool_args": {
"tool_name": "my_tool",
"description": "A custom code tool",
"enable_by_default": true,
"tool_usage_mode": ["runner", "creator"]
},
"owner_email": "user@example.com"
}
]
Update a custom tool​
Endpoint: PUT /api/v1/agents/custom_tools/{tool_id}
Update the configuration (tool_args) of an existing tool.
Path parameter
| Name | Type | Required | Description |
|---|---|---|---|
tool_id | string | Yes | ID of the custom tool to update (per user) |
Request body
application/json with the fields you want to change inside tool_args. For example:
{
"tool_args": {
"enable_by_default": false,
"tool_usage_mode": ["runner"]
}
}
Response
200 OKwith{ "agent_custom_tool_id": "<tool-id>" }if the tool was updated.400 Bad Requestwith"tool_args is required for update."iftool_argsis missing.404 Not Foundwith"Custom agent tool not found or no changes made."if the tool does not exist or no changes were applied.
Delete custom tools​
Endpoint: DELETE /api/v1/agents/custom_tools/{tool_ids}
Delete one or more custom tools for the authenticated user.
Path parameter
| Name | Type | Required | Description |
|---|---|---|---|
tool_ids | string[] | Yes | One or more tool IDs to be deleted |
Pass multiple IDs as a comma-separated list in the path, for example:
/api/v1/agents/custom_tools/id1,id2,id3
Response
200 OKwith a JSONCountindicating how many tools were deleted, for example:
{"count": 2}
Get a single custom tool​
Endpoint: GET /api/v1/agents/custom_tools/{tool_id}
Retrieve details for a single custom agent tool by ID.
Path parameter
| Name | Type | Required | Description |
|---|---|---|---|
tool_id | string | Yes | ID of the custom tool to retrieve |
Response
200 OKwith a JSON object containing the tool details:
{
"id": "uuid-string",
"tool_name": "my_tool",
"tool_type": "general_code",
"tool_args": {
"tool_name": "my_tool",
"description": "A custom code tool",
"enable_by_default": true
},
"owner_email": "user@example.com",
"file_name": "my_tool.py"
}
404 Not Foundif the tool does not exist or is not owned by the user.
Download a custom tool file​
Endpoint: GET /api/v1/agents/custom_tools/{tool_id}/download
Download the source file associated with a custom agent tool. Only local_mcp, browser_action, and general_code tool types support file download. To download through the UI instead, see Download a general code tool.
Path parameter
| Name | Type | Required | Description |
|---|---|---|---|
tool_id | string | Yes | ID of the custom tool whose file to download |
Response
200 OKwithapplication/octet-streambody and aContent-Dispositionheader containing the original filename.400 Bad Requestif the tool type does not support file download.404 Not Foundif the tool does not exist, is not owned by the user, or has no associated file.
Python SDK example
from h2ogpte import H2OGPTE
client = H2OGPTE(address="https://h2ogpte.genai.h2o.ai", api_key="sk-XXXXX...")
path = client.download_agent_tool_file(
tool_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
destination_directory="./downloads",
destination_file_name="my_tool.py", # optional: override the saved filename
)
print(f"Downloaded to: {path}")
The method raises FileExistsError if a file with the same name already exists in the destination directory. Use destination_file_name to specify a different name and avoid conflicts.
cURL example
curl -o tool_file.py \
-H "Authorization: Bearer sk-XXXXX..." \
"https://h2ogpte.genai.h2o.ai/api/v1/agents/custom_tools/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/download"
Custom Agents API​
Custom agents are standalone AI agent implementations packaged as ZIP files. Use this API to programmatically register, retrieve, update, and delete custom agents, and to manage their API key and MCP tool associations.
Authentication​
Use the same API key authentication as the main REST API. Write operations require custom-agent permissions: ManageCustomAgent for adding, updating, and managing associations (including creating and deleting tool and key associations). DeleteCustomAgent is required only for deleting the agents themselves. If the required permission is missing, the API returns 401 Unauthorized. Read operations (list and get) require only a valid API key, except GET /api/v1/agents/custom_agents/{agent_id}/suggestions, which requires ConfigureAgents.
Authorization: Bearer <your-api-key>
Add a custom agent​
Endpoint: POST /api/v1/agents/custom_agents
Registers a new custom agent by uploading a ZIP package. The request uses multipart/form-data encoding.
Parameters​
| Parameter | Type | Required | Description |
|---|---|---|---|
file | binary | Yes | .zip file containing one or more agent implementation folders |
agent_type | string | Yes | Agent framework. Accepted values: langgraph, crewai, openai, claude |
agent_args | JSON string | Yes | Agent configuration as a JSON-serialized string. For example: {"description": "My research agent"} |
agent_name | string | No | Override name for the agent. If provided and the ZIP contains exactly one agent folder, this name is used instead of the folder name inside the ZIP. |
Python SDK example​
from h2ogpte import H2OGPTE
client = H2OGPTE(address="https://h2ogpte.genai.h2o.ai", api_key="<your-api-key>")
agent_ids = client.add_custom_agent(
agent_type="langgraph",
agent_args={"description": "My research agent"},
agent_path="/path/to/agent.zip",
agent_name="research-agent", # optional
)
Returns: list[str] — list of created agent ID strings (UUIDs). The SDK extracts the agent_custom_agent_id field from each response object.
cURL example​
curl -X POST "https://h2ogpte.genai.h2o.ai/api/v1/agents/custom_agents" \
-H "Authorization: Bearer <your-api-key>" \
-F "agent_type=langgraph" \
-F 'agent_args={"description": "My research agent"}' \
-F "agent_name=research-agent" \
-F "file=@/path/to/agent.zip"
Response​
Success — 201 Created
Returns a JSON array of created agent objects:
[
{
"agent_custom_agent_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
]
For ZIP files containing multiple agent folders, the response contains one entry per registered agent.
Error responses
| Status | Message | Cause |
|---|---|---|
| 400 | "Failed to parse form data." | Request body is not valid multipart/form-data |
| 400 | "Invalid JSON format for agent_args." | agent_args is not valid JSON |
| 400 | "The request does not contain a file." | File is missing |
| 401 | "Unauthorized" | Missing or invalid API key, or the user lacks ManageCustomAgent permission |
| 415 | "Invalid file extension: {ext}. Allowed extensions are .zip." | Uploaded file is not a .zip |
| 413 | "File is too large, maximum size is 20MB" | Uploaded file exceeds the 20 MB size limit |
Error response body format:
{
"code": 400,
"message": "The request does not contain a file."
}
List custom agents​
Endpoint: GET /api/v1/agents/custom_agents
Returns all custom agents owned by the authenticated user.
Python SDK example​
agents = client.get_custom_agents()
for agent in agents:
print(agent["agent_name"], agent["agent_type"])
Returns: List[dict] — each dict contains id, agent_name, agent_type, agent_args, owner_email, mcp_servers, api_keys.
Get a custom agent​
Endpoint: GET /api/v1/agents/custom_agents/{agent_id}
Returns a single custom agent by ID.
Parameters​
| Parameter | Type | Required | Description |
|---|---|---|---|
agent_id | string (UUID) | Yes | Path parameter — unique identifier of the agent |
Python SDK example​
agent = client.get_custom_agent(agent_id="<agent-uuid>")
Returns: dict — keys: id, agent_name, agent_type, agent_args, owner_email, mcp_servers, api_keys.
Raises: NotFoundError if the agent does not exist or is not owned by the authenticated user.
Update a custom agent​
Endpoint: PUT /api/v1/agents/custom_agents/{agent_id}
Updates a custom agent's arguments and optional MCP server mappings.
Parameters​
| Parameter | Type | Required | Description |
|---|---|---|---|
agent_id | string (UUID) | Yes | Path parameter — ID of the agent to update |
agent_args | dict | Yes | New agent configuration arguments |
mcp_servers_mapping | dict | null | No | Maps MCP server names declared in the agent's code to platform tool names. Set a value to null to clear a mapping. For example: {"web_search": "my_search_tool", "db": null} |
Python SDK example​
updated_id = client.update_custom_agent(
agent_id="<agent-uuid>",
agent_args={"description": "Updated description"},
mcp_servers_mapping={"web_search": "my_web_search_tool"},
)
Returns: str — the same agent ID that was passed in, confirming the update was applied.
Delete custom agents​
Endpoint: DELETE /api/v1/agents/custom_agents/{agent_ids}
Deletes one or more custom agents owned by the authenticated user.
Parameters​
| Parameter | Type | Required | Description |
|---|---|---|---|
agent_ids | string[] | Yes | Path parameter — one or more agent UUIDs as a comma-separated list |
Python SDK example​
count = client.delete_custom_agent(agent_ids=["<agent-uuid>"])
Returns: int — count of deleted agents.
cURL example​
curl -X DELETE "https://h2ogpte.genai.h2o.ai/api/v1/agents/custom_agents/<agent-uuid-1>,<agent-uuid-2>" \
-H "Authorization: Bearer <your-api-key>"
Response​
Success — 200 OK
{ "count": 1 }
List all agents​
Endpoint: GET /api/v1/agents
Returns all agents available to the authenticated user — both built-in platform agents and custom agents.
Python SDK example​
all_agents = client.get_all_agents()
for agent in all_agents:
print(agent["label"], agent["type"])
Returns: List[dict] — each dict contains id, value, label, enabled, type, owner, description, api_keys (grouped into optional, required, and custom), and mcp_servers (custom agents only).
Get agent suggestions​
Endpoint: GET /api/v1/agents/custom_agents/{agent_id}/suggestions
Returns MCP tool suggestions for a custom agent based on its metadata.
Parameters​
| Parameter | Type | Required | Description |
|---|---|---|---|
agent_id | string (UUID) | Yes | Path parameter - custom agent ID |
Python SDK example​
suggestions = client.get_agent_suggestions(agent_id="<agent-uuid>")
Returns: List[dict] — each dict contains mcp_servers, where each item includes tool_name and tool_args.
Error responses
| Status | Cause |
|---|---|
| 401 | Missing or invalid API key, or missing ConfigureAgents permission |
| 404 | Custom agent not found |
| 500 | Internal server error |
Manage tool associations​
Tool associations link the MCP server names declared in an agent's code to the platform tools configured in the Tools tab.
List tool associations​
Endpoint: GET /api/v1/agents/custom_agent_tool_associations
| Query parameter | Type | Required | Description |
|---|---|---|---|
agent_id | string (UUID) | No | Filter associations by agent ID |
agent_name | string | No | Filter associations by agent name |
Python SDK example​
associations = client.list_custom_agent_tool_associations(
agent_id="<agent-uuid>", # optional
agent_name="research-agent", # optional
)
Returns: List[dict] — each dict contains id, agent_id, agent_name, tool_id, tool_name, mcp_server_name, user_id.
Create a tool association​
Endpoint: POST /api/v1/agents/custom_agent_tool_associations
| Parameter | Type | Required | Description |
|---|---|---|---|
agent_id | string (UUID) | Yes | The custom agent to associate |
mcp_server_name | string | Yes | The MCP server name as declared in the agent's code |
tool_name | string | null | No | The platform tool name from the Tools tab. Omit or pass null to create an unresolved association. |
Python SDK example​
association = client.create_custom_agent_tool_association(
agent_id="<agent-uuid>",
mcp_server_name="web_search",
tool_name="my_web_search_tool", # optional
)
Returns: dict — the created association object with keys id, agent_id, agent_name, tool_id, tool_name, mcp_server_name, user_id.
Delete tool associations​
Endpoint: DELETE /api/v1/agents/custom_agent_tool_associations/{association_ids}
Deletes one or more tool associations owned by the authenticated user.
| Parameter | Type | Required | Description |
|---|---|---|---|
association_ids | string[] | Yes | Path parameter — one or more association UUIDs as a comma-separated list |
Python SDK example​
deleted_count = client.delete_custom_agent_tool_associations(
association_ids=["<association-uuid>"]
)
Returns: int — number of associations deleted.
Response — 200 OK
{ "deleted_count": 1 }
Manage key associations​
Key associations map the environment variable names declared in an agent's envs.json file to secrets stored in the platform's Secret Manager.
List key associations​
Endpoint: GET /api/v1/agents/custom_agent_key_associations
| Query parameter | Type | Required | Description |
|---|---|---|---|
agent_id | string (UUID) | No | Filter associations by agent ID |
Python SDK example​
key_assocs = client.list_custom_agent_key_associations(agent_id="<agent-uuid>")
Returns: List[dict] — each dict contains id, agent_id, env_key_name, key_id, user_id, requirement_type (one of required, optional_with_default, optional_no_default, custom), key_name, owner_email.
Create a key association​
Endpoint: POST /api/v1/agents/custom_agent_key_associations
| Parameter | Type | Required | Description |
|---|---|---|---|
agent_id | string (UUID) | Yes | The custom agent to associate |
env_key_name | string | Yes | The environment variable name as declared in the agent's envs.json file |
key_id | string (UUID) | Yes | The platform secret ID to bind to this environment variable |
Python SDK example​
key_assoc = client.create_custom_agent_key_association(
agent_id="<agent-uuid>",
env_key_name="CUSTOM_AGENT_API_KEY",
key_id="<secret-uuid>",
)
Returns: dict — keys: id, agent_id, env_key_name, key_id, user_id, requirement_type, key_name, owner_email.
Delete key associations​
Endpoint: DELETE /api/v1/agents/custom_agent_key_associations/{association_ids}
Deletes one or more key associations owned by the authenticated user.
| Parameter | Type | Required | Description |
|---|---|---|---|
association_ids | string[] | Yes | Path parameter — one or more association UUIDs as a comma-separated list |
Python SDK example​
deleted_count = client.delete_custom_agent_key_associations(
association_ids=["<association-uuid>"]
)
Returns: int — number of associations deleted.
Response — 200 OK
{ "deleted_count": 1 }
- Submit and view feedback for this page
- Send feedback about Enterprise h2oGPTe to cloud-feedback@h2o.ai