Skip to content

Instantly share code, notes, and snippets.

@win3zz
Last active April 11, 2026 14:48
Show Gist options
  • Select an option

  • Save win3zz/80ef0ba4becebdd26903cea60e7c7579 to your computer and use it in GitHub Desktop.

Select an option

Save win3zz/80ef0ba4becebdd26903cea60e7c7579 to your computer and use it in GitHub Desktop.
Manus ApiProxyService CallApi Endpoint
import json
import os
from pathlib import Path
from typing import Any, cast
import requests
class ApiClient:
"""
A client class for making requests to an internal API aggregation platform.
This class provides a simple interface to call APIs through an internal proxy service
that aggregates multiple external APIs.
"""
def __init__(self):
"""
Initialize the API client with the base host URL for the proxy service.
"""
host = os.getenv('RUNTIME_API_HOST', 'https://api.manus.im')
self.host = f'{host}/apiproxy.v1.ApiProxyService/CallApi'
with Path().home().joinpath('.secrets/sandbox_api_token').open('r') as f:
self.token = f.read().strip()
def _convert_bool_to_str(self, data: dict[str, Any] | None) -> dict[str, Any] | None:
"""Convert boolean values in dictionary to strings.
Args:
data (dict | None): Input dictionary that may contain boolean values
Returns:
dict | None: Dictionary with boolean values converted to strings, or None if input is None
"""
if data is None:
return None
result: dict[str, Any] = {}
for key, value in data.items():
if isinstance(value, bool):
result[key] = str(value).lower()
elif isinstance(value, dict):
result[key] = self._convert_bool_to_str(cast(dict[str, Any], value))
else:
result[key] = value
return result
def call_api(
self,
api_id_or_name: str,
body: dict[str, Any] | None = None,
query: dict[str, Any] | None = None,
path_params: dict[str, Any] | None = None,
multipart_form_data: dict[str, Any] | None = None,
) -> dict[str, Any]:
"""
Make an API call through the proxy service.
Args:
api_id_or_name (str): The ID or name of the API to call
body (dict, optional): The request body to send. Defaults to None.
query (dict, optional): The query parameters to send. Defaults to None.
path_params (dict, optional): The path parameters to send. Defaults to None.
multipart_form_data (dict, optional): The multipart form data to send. Defaults to None.
Returns:
dict: The JSON response from the API call, or an error dict if the call fails
"""
try:
resp = requests.post(
f'{self.host}',
json={
'apiId': api_id_or_name,
'body': self._convert_bool_to_str(body),
'query': self._convert_bool_to_str(query),
'path_params': self._convert_bool_to_str(path_params),
'multipart_form_data': self._convert_bool_to_str(multipart_form_data),
},
headers={'x-sandbox-token': self.token},
)
data = resp.json()
if 'jsonData' in data:
return json.loads(data['jsonData'])
else:
return data
except Exception as e:
return {'error': str(e)}

Manus ApiProxyService CallApi Endpoint Information

Overview

The https://api.manus.im/apiproxy.v1.ApiProxyService/CallApi endpoint is a central proxy service used by Manus to route requests to internal sandbox services. It acts as an intermediary that handles authentication, routing, and access control.

Request Structure

The endpoint accepts a POST request with a JSON body.

Headers

  • x-sandbox-token: Required. The API token for authentication (usually found in $HOME/.secrets/sandbox_api_token).
  • Content-Type: application/json

Body Parameters

The JSON body typically includes:

  • apiId: String. The ID or name of the internal API to call.
  • body: Object (optional). The request body to be passed to the internal API.
  • query: Object (optional). Query parameters to be passed to the internal API.

Internal API Endpoints (apiId)

Based on reverse-engineered documentation, the proxy can route to several internal services:

1. Browser Actions (/browser/action)

  • apiId: /browser/action
  • body: A BrowserActionRequest object.
  • Example Actions: navigate, click, input, screenshot, scroll, press_key, select_option, hover.

2. Terminal Operations (/terminal/{terminal_id}/...)

  • apiId: /terminal/{terminal_id}/write, /terminal/{terminal_id}/reset, etc.
  • body: Parameters for the terminal command (e.g., command, stdin).

3. File Operations (/file, /file/upload_to_s3)

  • apiId: /file/upload_to_s3, /file/multipart_upload_to_s3, /file (GET).
  • body: File path, S3 presigned URL, etc.

4. Text Editor (/text_editor)

  • apiId: /text_editor
  • body: Action (e.g., view, create, write, replace, undo) and file path.

Other:

Example Call (Python)

import requests
import json

url = "https://api.manus.im/apiproxy.v1.ApiProxyService/CallApi"
token = "YOUR_SANDBOX_TOKEN"

headers = {
    "x-sandbox-token": token,
    "Content-Type": "application/json"
}

# Example: Navigate the browser to a URL
payload = {
    "apiId": "/browser/action",
    "body": {
        "action": "navigate",
        "url": "https://www.google.com"
    }
}

response = requests.post(url, headers=headers, json=payload)
print(response.json())

Response

The response is typically a JSON object containing the result of the internal API call. If the call is successful, the data is often nested under a jsonData key.

Reference

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment