Invoke Tool
curl --request POST \
--url https://api.truthlocks.com/v1/tools/{toolName}/invoke \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"session_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"arguments": {}
}
'import requests
url = "https://api.truthlocks.com/v1/tools/{toolName}/invoke"
payload = {
"session_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"arguments": {}
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({session_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a', arguments: {}})
};
fetch('https://api.truthlocks.com/v1/tools/{toolName}/invoke', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.truthlocks.com/v1/tools/{toolName}/invoke",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'session_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'arguments' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.truthlocks.com/v1/tools/{toolName}/invoke"
payload := strings.NewReader("{\n \"session_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"arguments\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.truthlocks.com/v1/tools/{toolName}/invoke")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"session_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"arguments\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.truthlocks.com/v1/tools/{toolName}/invoke")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"session_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"arguments\": {}\n}"
response = http.request(request)
puts response.read_body{
"result": {},
"receipt_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"execution_ms": 123
}{
"code": "AUTH_REQUIRED",
"message": "Authentication required",
"http_status": 401
}{
"code": "AUTH_REQUIRED",
"message": "Authentication required",
"http_status": 401
}{
"code": "AUTH_REQUIRED",
"message": "Authentication required",
"http_status": 401
}{
"code": "AUTH_REQUIRED",
"message": "Authentication required",
"http_status": 401
}Agent Sessions & Tools
Invoke Tool
Request tool invocation with scope validation, rate limiting, and audit receipt generation
POST
/
v1
/
tools
/
{toolName}
/
invoke
Invoke Tool
curl --request POST \
--url https://api.truthlocks.com/v1/tools/{toolName}/invoke \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"session_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"arguments": {}
}
'import requests
url = "https://api.truthlocks.com/v1/tools/{toolName}/invoke"
payload = {
"session_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"arguments": {}
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({session_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a', arguments: {}})
};
fetch('https://api.truthlocks.com/v1/tools/{toolName}/invoke', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.truthlocks.com/v1/tools/{toolName}/invoke",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'session_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'arguments' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.truthlocks.com/v1/tools/{toolName}/invoke"
payload := strings.NewReader("{\n \"session_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"arguments\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.truthlocks.com/v1/tools/{toolName}/invoke")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"session_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"arguments\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.truthlocks.com/v1/tools/{toolName}/invoke")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"session_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"arguments\": {}\n}"
response = http.request(request)
puts response.read_body{
"result": {},
"receipt_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"execution_ms": 123
}{
"code": "AUTH_REQUIRED",
"message": "Authentication required",
"http_status": 401
}{
"code": "AUTH_REQUIRED",
"message": "Authentication required",
"http_status": 401
}{
"code": "AUTH_REQUIRED",
"message": "Authentication required",
"http_status": 401
}{
"code": "AUTH_REQUIRED",
"message": "Authentication required",
"http_status": 401
}Invoke Tool
POST /v1/tools/{toolName}/invoke
Requests invocation of a registered tool on behalf of a machine agent. The platform performs a multi-layer access control check before granting access:
- Agent status — agent must be
"active" - Scope check — agent must hold the tool’s required scope
- Rate limit — agent must not exceed the tool’s per-minute rate limit
- Approval gate — if the tool requires approval, invocation is deferred to the approval queue
This endpoint performs the access control decision and generates an audit
receipt. It does not proxy the actual tool execution. Your application is
responsible for calling the tool’s underlying endpoint after receiving an
"allowed" response.Authentication
RequiresX-API-Key header or Bearer JWT token. Tenant-scoped via X-Tenant-ID.
Path Parameters
string
required
The registered tool name (e.g.,
"search.web", "crm-contact-lookup").Request Body
string
required
The MAIP agent identifier requesting the tool invocation (e.g.,
maip:t1234567:01HYX3KPZQ7RJGBN0WFMV8SDEH).string
The active session ID, if the invocation is scoped to a session. Optional but
recommended for full audit trail linkage.
Response
boolean
Whether the invocation was authorized.
true if all access control checks
passed.string
Invocation status. One of:
"allowed", "denied", "pending_approval".string
Human-readable explanation when the invocation is denied or pending. Not
present when allowed.
string
Unique receipt identifier for the invocation, linking to the audit trail. Only
present when
status is "allowed".boolean
true when the tool requires human approval and the invocation is queued.
Only present when status is "pending_approval".string
Identifier for the pending approval request. Use this to check approval status
or to approve/reject via the approvals API. Only present when
status is
"pending_approval".Example: Allowed Invocation
curl -X POST https://api.truthlocks.com/v1/tools/search.web/invoke \
-H "X-API-Key: tl_live_..." \
-H "Content-Type: application/json" \
-d '{
"agent_id": "maip:t1234567:01HYX3KPZQ7RJGBN0WFMV8SDEH",
"session_id": "maip-sess:a1b2c3d4:9f8e7d6c5b4a3210"
}'
Access Control Flow
POST /v1/tools/{name}/invoke
|
+-- Is agent active?
| No --> { allowed: false, status: "denied", reason: "agent is not active" }
|
+-- Does agent have required scope?
| No --> { allowed: false, status: "denied", reason: "agent lacks required scope: ..." }
|
+-- Is rate limit exceeded?
| Yes --> { allowed: false, status: "denied", reason: "rate limit exceeded" }
|
+-- Does tool require approval?
| Yes --> { allowed: false, status: "pending_approval", requires_approval: true }
|
+-- Create receipt + record invocation
--> { allowed: true, status: "allowed", receipt_id: "..." }
Integration Pattern
After receiving an"allowed" response, execute the tool and optionally record the outcome:
# 1. Request invocation authorization
RESPONSE=$(curl -s -X POST https://api.truthlocks.com/v1/tools/search.web/invoke \
-H "X-API-Key: tl_live_..." \
-H "Content-Type: application/json" \
-d '{"agent_id": "maip:t1234567:01HYX3KPZQ7RJGBN0WFMV8SDEH"}')
ALLOWED=$(echo "$RESPONSE" | jq -r '.allowed')
RECEIPT_ID=$(echo "$RESPONSE" | jq -r '.receipt_id')
# 2. Execute the tool if authorized
if [ "$ALLOWED" = "true" ]; then
RESULT=$(curl -s "https://serpapi.com/search?q=example&api_key=...")
echo "Tool executed. Receipt: $RECEIPT_ID"
fi
Authorizations
API key for machine-to-machine authentication
Path Parameters
Tool identifier
Body
application/json

