curl --request POST \
--url https://app.withrealm.com/api/external/alpha/chats/{chat_id}/approvals \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"assistant_message_id": "msg_5f6g",
"responses": [
{
"tool_call_id": "call_abc123",
"approved": true
},
{
"tool_call_id": "call_def456",
"approved": false,
"reason": "Not authorized to send external email."
}
]
}
'import requests
url = "https://app.withrealm.com/api/external/alpha/chats/{chat_id}/approvals"
payload = {
"assistant_message_id": "msg_5f6g",
"responses": [
{
"tool_call_id": "call_abc123",
"approved": True
},
{
"tool_call_id": "call_def456",
"approved": False,
"reason": "Not authorized to send external email."
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
assistant_message_id: 'msg_5f6g',
responses: [
{tool_call_id: 'call_abc123', approved: true},
{
tool_call_id: 'call_def456',
approved: false,
reason: 'Not authorized to send external email.'
}
]
})
};
fetch('https://app.withrealm.com/api/external/alpha/chats/{chat_id}/approvals', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.withrealm.com/api/external/alpha/chats/{chat_id}/approvals"
payload := strings.NewReader("{\n \"assistant_message_id\": \"msg_5f6g\",\n \"responses\": [\n {\n \"tool_call_id\": \"call_abc123\",\n \"approved\": true\n },\n {\n \"tool_call_id\": \"call_def456\",\n \"approved\": false,\n \"reason\": \"Not authorized to send external email.\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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))
}require 'uri'
require 'net/http'
url = URI("https://app.withrealm.com/api/external/alpha/chats/{chat_id}/approvals")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"assistant_message_id\": \"msg_5f6g\",\n \"responses\": [\n {\n \"tool_call_id\": \"call_abc123\",\n \"approved\": true\n },\n {\n \"tool_call_id\": \"call_def456\",\n \"approved\": false,\n \"reason\": \"Not authorized to send external email.\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.withrealm.com/api/external/alpha/chats/{chat_id}/approvals",
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([
'assistant_message_id' => 'msg_5f6g',
'responses' => [
[
'tool_call_id' => 'call_abc123',
'approved' => true
],
[
'tool_call_id' => 'call_def456',
'approved' => false,
'reason' => 'Not authorized to send external email.'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"id": "cht_9x8y7z",
"assistant_id": "agt_1a2b3c",
"agent_id": "agt_1a2b3c",
"created": 1730210400000,
"created_date": "2024-10-29T14:00:00.000Z",
"content": "Your Q3 revenue grew 12% quarter over quarter.",
"research_mode": false,
"output_format": "markdown",
"status": "completed"
}{
"error": "<string>",
"details": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "generation_in_flight",
"message": "Another answer is already being generated in this chat. Retry after 8 seconds, or start a new chat.",
"retry_after_seconds": 8
}{
"error": "<string>"
}{
"error": "<string>"
}Resume a paused chat after tool approval
Submit ask-first approval decisions for a paused chat and continue the agent run.
Rate Limits
600 requests per minute.
curl --request POST \
--url https://app.withrealm.com/api/external/alpha/chats/{chat_id}/approvals \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"assistant_message_id": "msg_5f6g",
"responses": [
{
"tool_call_id": "call_abc123",
"approved": true
},
{
"tool_call_id": "call_def456",
"approved": false,
"reason": "Not authorized to send external email."
}
]
}
'import requests
url = "https://app.withrealm.com/api/external/alpha/chats/{chat_id}/approvals"
payload = {
"assistant_message_id": "msg_5f6g",
"responses": [
{
"tool_call_id": "call_abc123",
"approved": True
},
{
"tool_call_id": "call_def456",
"approved": False,
"reason": "Not authorized to send external email."
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
assistant_message_id: 'msg_5f6g',
responses: [
{tool_call_id: 'call_abc123', approved: true},
{
tool_call_id: 'call_def456',
approved: false,
reason: 'Not authorized to send external email.'
}
]
})
};
fetch('https://app.withrealm.com/api/external/alpha/chats/{chat_id}/approvals', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.withrealm.com/api/external/alpha/chats/{chat_id}/approvals"
payload := strings.NewReader("{\n \"assistant_message_id\": \"msg_5f6g\",\n \"responses\": [\n {\n \"tool_call_id\": \"call_abc123\",\n \"approved\": true\n },\n {\n \"tool_call_id\": \"call_def456\",\n \"approved\": false,\n \"reason\": \"Not authorized to send external email.\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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))
}require 'uri'
require 'net/http'
url = URI("https://app.withrealm.com/api/external/alpha/chats/{chat_id}/approvals")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"assistant_message_id\": \"msg_5f6g\",\n \"responses\": [\n {\n \"tool_call_id\": \"call_abc123\",\n \"approved\": true\n },\n {\n \"tool_call_id\": \"call_def456\",\n \"approved\": false,\n \"reason\": \"Not authorized to send external email.\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.withrealm.com/api/external/alpha/chats/{chat_id}/approvals",
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([
'assistant_message_id' => 'msg_5f6g',
'responses' => [
[
'tool_call_id' => 'call_abc123',
'approved' => true
],
[
'tool_call_id' => 'call_def456',
'approved' => false,
'reason' => 'Not authorized to send external email.'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"id": "cht_9x8y7z",
"assistant_id": "agt_1a2b3c",
"agent_id": "agt_1a2b3c",
"created": 1730210400000,
"created_date": "2024-10-29T14:00:00.000Z",
"content": "Your Q3 revenue grew 12% quarter over quarter.",
"research_mode": false,
"output_format": "markdown",
"status": "completed"
}{
"error": "<string>",
"details": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "generation_in_flight",
"message": "Another answer is already being generated in this chat. Retry after 8 seconds, or start a new chat.",
"retry_after_seconds": 8
}{
"error": "<string>"
}{
"error": "<string>"
}When to use this endpoint
Use this endpoint afterPOST /chats returns status: "approval_required" or POST /chats-streaming emits a tool_approval_request event. Submit approval decisions for the pending tool calls to continue the same chat.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
The ID of the chat that is currently paused waiting for tool approval.
Body
The paused assistant message that is awaiting approval
Response
Success
- Option 1
- Option 2
Unique identifier for the chat
Deprecated. Use agent_id instead.
The ID of the agent that processed the request
Unix timestamp in milliseconds of when the completion was created
ISO 8601 formatted timestamp of when the completion was created
The content of the chat
If research mode was used for this chat. The agent configuration can override the user requested value.
The format of the content returned
markdown, text Whether the chat completed immediately or was queued
completed, queued Normalized persisted turn trace returned only for authorized eval requests
Hide child attributes
Hide child attributes
1 completed, approval_required, failed, aborted test, o1, o3, o1-mini, o3-mini, o4-mini, gpt-image-2, azure-gpt-5.6-terra-credits, azure-gpt-5.6-luna-credits, azure-gpt-5.5-credits, azure-gpt-5.4-credits, azure-gpt-5.4-mini-credits, azure-gpt-5.1-credits, azure-finetuned-mini-1, azure-finetuned-filtersearch-1, azure-finetuned-filtersearch-2, azure-finetuned-filtersearch-3, vertex-finetuned-1, vertex-finetuned-2, azure-o1, azure-o3, azure-o1-mini, azure-o3-mini, azure-o4-mini, vertex-claude-3-7-sonnet@20250219, vertex-claude-3-5-sonnet@20240620, vertex-claude-3-5-sonnet-v2@20241022, vertex-claude-3-haiku@20240307, vertex-claude-3-opus@20240229, vertex-claude-opus-4@20250514, vertex-claude-sonnet-4@20250514, vertex-claude-sonnet-4-5@20250929, vertex-claude-opus-4-5@20251101, vertex-claude-opus-4-6@default, vertex-claude-opus-4-7@global, vertex-claude-opus-4-7@eu, vertex-claude-sonnet-5@eu, vertex-claude-opus-4-8@global, vertex-claude-opus-4-8@eu, vertex-claude-sonnet-4-6, vertex-claude-haiku-4-5@20251001, bedrock-anthropic.claude-opus-4-5-20251101-v1:0, bedrock-anthropic.claude-opus-4-6-v1, bedrock-anthropic.claude-opus-4-7, bedrock-anthropic.claude-opus-4-8, bedrock-anthropic.claude-sonnet-4-6, bedrock-anthropic.claude-sonnet-4-5-20250929-v1:0, bedrock-us-anthropic.claude-sonnet-4-20250514-v1:0, bedrock-eu-anthropic.claude-sonnet-4-20250514-v1:0, bedrock-eu-anthropic.claude-3-7-sonnet-20250219-v1:0, bedrock-eu-anthropic.claude-3-5-sonnet-20240620-v1:0, bedrock-eu-anthropic.claude-3-5-haiku-20241022-v1:0, bedrock-anthropic.claude-haiku-4-5-20251001-v1:0, claude-sonnet-4-20250514, claude-sonnet-4-6, claude-sonnet-5, claude-opus-4-6, claude-opus-4-7, claude-opus-4-8, claude-haiku-4-5-20251001, claude-sonnet-4-5-20250929, claude-3-7-sonnet-latest, claude-3-7-sonnet-20250219, claude-3-5-sonnet-20241022, groq-mixtral, google-gemini-1.5-pro-001, google-gemini-1.5-flash-001, google-gemini-2.0-flash-001, google-gemini-2.5-pro, google-gemini-2.5-flash, google-gemini-2.5-flash-lite, google-gemini-2.5-flash-image, google-gemini-3.1-flash-lite, google-gemini-3.1-flash-lite-eu, google-gemini-3.1-flash-image, google-gemini-3.5-flash-lite, google-gemini-3.5-flash-lite-eu, google-gemini-3.5-flash, google-gemini-3.5-flash-eu, google-gemini-3.6-flash, gemini-2.0-flash-001, gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite, gemini-2.5-flash-image, gemini-3.1-flash-lite, gemini-3.1-flash-image, gemini-3.5-flash-lite, gemini-3.5-flash, gemini-3.6-flash, gemini-3-pro, gemini-3-flash, google-gemini-3-flash, google-gemini-3-pro, finetuned-mini, finetuned-mini-2, finetuned-mini-3, finetuned-filtersearch-1, finetuned-gpt41mini-1, finetuned-4o, qwen-7b, flow-judge, llama-3.2-3b, cerebras-llama-3.3-70b, nebius-kimi-k2.5, nebius-gpt-oss-120b, nebius-gpt-oss-20b, nebius-qwen3-30b-thinking, nebius-nemotron-nano-30b, nebius-glm-4.5-air, nebius-minimax-m2.1, azure-deepseek-v4-flash, tensorx-deepseek-v4-flash, tensorx-deepseek-v4-flash-0731, gmicloud-deepseek-v4-flash, deepinfra-deepseek-v4-flash, deepinfra-deepseek-v4-flash-0731, openrouter-deepseek-v4-flash, novita-deepseek-v4-flash, novita-deepseek-v4-pro, novita-mimo-v2.5, digitalocean-mimo-v2.5, deepinfra-mimo-v2.5, novita-gemma-4-26b-a4b-it, novita-qwen3-coder-30b-a3b-instruct, novita-gpt-oss-120b, novita-gpt-oss-20b, novita-ling-2.6-flash, novita-minimax-m3, deepinfra-minimax-m3, novita-hy3, deepinfra-hy3, novita-step-3.7-flash, deepinfra-step-3.7-flash low, medium, high, max Models that completed calls during the turn, in call order. Null means model telemetry was unavailable.
Hide child attributes
Hide child attributes
x >= 0realm, provider proposed, approval_required, denied, succeeded, failed Hide child attributes
Hide child attributes
x >= 0x >= 0x >= 0x >= 0x >= 0x >= 0x >= 0x >= 0Hide child attributes
Hide child attributes
x >= 0x >= 0x >= 0x >= 0x >= 0
