curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"tool_call_id": "toolu_01A9FJd3kP2mNqRs7VwXyZ4b",
"action": "approved"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input"
payload = {
"tool_call_id": "toolu_01A9FJd3kP2mNqRs7VwXyZ4b",
"action": "approved"
}
headers = {
"api_key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {api_key: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({tool_call_id: 'toolu_01A9FJd3kP2mNqRs7VwXyZ4b', action: 'approved'})
};
fetch('https://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input', 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://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input",
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([
'tool_call_id' => 'toolu_01A9FJd3kP2mNqRs7VwXyZ4b',
'action' => 'approved'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input"
payload := strings.NewReader("{\n \"tool_call_id\": \"toolu_01A9FJd3kP2mNqRs7VwXyZ4b\",\n \"action\": \"approved\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("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://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"tool_call_id\": \"toolu_01A9FJd3kP2mNqRs7VwXyZ4b\",\n \"action\": \"approved\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api_key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"tool_call_id\": \"toolu_01A9FJd3kP2mNqRs7VwXyZ4b\",\n \"action\": \"approved\"\n}"
response = http.request(request)
puts response.read_body{
"id": "6820f3a4e7b91d003c45a1f2",
"name": "My CRM",
"status": {
"state": "ready",
"details": "Publishing app",
"request_id": "a1b2c3d4e5f67890abcdef12",
"last_updated_date": "2026-08-02T14:30:00Z",
"error_source": "build",
"paywall_context": {
"billing_organization_id": "67e0b12c4d8a3f005b21c9e4",
"user_id": "6706af53b9c1e2004a37d85f",
"evaluated_at": "2026-08-02T14:30:00Z"
}
},
"conversation": {
"id": "1f0c2b7a-9d51-4c3e-8a62-7b4d5e6f8a90",
"messages": [
{
"id": "7f3a1c88-52d4-4a0e-9b31-2c6f0d8e4a19",
"role": "assistant",
"content": "I added a contact form to the home page.",
"file_urls": [
"https://example.com/mockup.png"
],
"hidden": false,
"checkpoint_id": "6886b8d390dc7e2f4a2c91b3",
"tool_calls": [
{
"id": "toolu_01A9FJd3kP2mNqRs7VwXyZ4b",
"name": "create_file",
"status": "waiting_for_user_input",
"requires_user_input": true,
"arguments_string": "{\"file_path\": \"src/pages/Home.jsx\", \"content\": \"export default function Home() {}\"}"
}
],
"usage": {
"prompt_tokens": 18432,
"completion_tokens": 742,
"credits_charged": 1.5
},
"metadata": {
"created_date": "2026-08-02T14:30:00",
"created_by_email": "developer@example.com"
}
}
]
}
}Submit tool-call input
Approves or rejects one tool call the AI is waiting on, then resumes the turn.
Some steps pause for you before they run. The turn stops with an assistant message whose tool call has no result yet, and the AI waits. Answer it here to let the turn continue. Use Read conversation messages to find the tool call that is waiting and take its ID.
The request stays open until the resumed turn settles, so it can take several minutes. Resuming a turn consumes credits. To answer several waiting tool calls at once, use Submit tool-call input (batch).
Set an X-Request-ID header before you send. A network retry carrying the same value is ignored rather than resumed a second time and charged again.
A 200 response does not mean the turn succeeded. Two cases come back as a 200.
- The turn ran and finished.
status.stateisreadyand the app is idle again. - The turn ran and failed.
status.stateiserror, andstatus.error_sourcesays where it failed. A value ofpaywallmeans the app’s workspace has no credits left.
curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"tool_call_id": "toolu_01A9FJd3kP2mNqRs7VwXyZ4b",
"action": "approved"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input"
payload = {
"tool_call_id": "toolu_01A9FJd3kP2mNqRs7VwXyZ4b",
"action": "approved"
}
headers = {
"api_key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {api_key: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({tool_call_id: 'toolu_01A9FJd3kP2mNqRs7VwXyZ4b', action: 'approved'})
};
fetch('https://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input', 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://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input",
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([
'tool_call_id' => 'toolu_01A9FJd3kP2mNqRs7VwXyZ4b',
'action' => 'approved'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input"
payload := strings.NewReader("{\n \"tool_call_id\": \"toolu_01A9FJd3kP2mNqRs7VwXyZ4b\",\n \"action\": \"approved\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("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://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"tool_call_id\": \"toolu_01A9FJd3kP2mNqRs7VwXyZ4b\",\n \"action\": \"approved\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/chat/submit-tool-call-input")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api_key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"tool_call_id\": \"toolu_01A9FJd3kP2mNqRs7VwXyZ4b\",\n \"action\": \"approved\"\n}"
response = http.request(request)
puts response.read_body{
"id": "6820f3a4e7b91d003c45a1f2",
"name": "My CRM",
"status": {
"state": "ready",
"details": "Publishing app",
"request_id": "a1b2c3d4e5f67890abcdef12",
"last_updated_date": "2026-08-02T14:30:00Z",
"error_source": "build",
"paywall_context": {
"billing_organization_id": "67e0b12c4d8a3f005b21c9e4",
"user_id": "6706af53b9c1e2004a37d85f",
"evaluated_at": "2026-08-02T14:30:00Z"
}
},
"conversation": {
"id": "1f0c2b7a-9d51-4c3e-8a62-7b4d5e6f8a90",
"messages": [
{
"id": "7f3a1c88-52d4-4a0e-9b31-2c6f0d8e4a19",
"role": "assistant",
"content": "I added a contact form to the home page.",
"file_urls": [
"https://example.com/mockup.png"
],
"hidden": false,
"checkpoint_id": "6886b8d390dc7e2f4a2c91b3",
"tool_calls": [
{
"id": "toolu_01A9FJd3kP2mNqRs7VwXyZ4b",
"name": "create_file",
"status": "waiting_for_user_input",
"requires_user_input": true,
"arguments_string": "{\"file_path\": \"src/pages/Home.jsx\", \"content\": \"export default function Home() {}\"}"
}
],
"usage": {
"prompt_tokens": 18432,
"completion_tokens": 742,
"credits_charged": 1.5
},
"metadata": {
"created_date": "2026-08-02T14:30:00",
"created_by_email": "developer@example.com"
}
}
]
}
}Authorizations
Personal API key.
Path Parameters
ID of the app whose AI chat this request acts on.
Body
ID of the tool call to answer. Read it off the waiting assistant message returned by Read conversation messages.
"toolu_01A9FJd3kP2mNqRs7VwXyZ4b"
Whether to let the tool call run or turn it down. Rejecting tells the AI to continue without doing that step.
approved, rejected "approved"
Response
Successful Response
An app, with its conversation and build status.
ID of the app.
"6820f3a4e7b91d003c45a1f2"
Display name of the app.
"My CRM"
The app's build status once the request returned. Read state to tell a finished turn from one that is still processing or that failed.
Show child attributes
Show child attributes
The app's conversation, including the messages this request produced.
Show child attributes
Show child attributes
Was this page helpful?