Run a Function in real time
curl --request POST \
--url https://your-sutro-deployment.example.com/v1/functions/{name}/run \
--header 'Authorization: <authorization>' \
--header 'Content-Type: <content-type>' \
--data '{
"input": {}
}'import requests
url = "https://your-sutro-deployment.example.com/v1/functions/{name}/run"
payload = { "input": {} }
headers = {
"Authorization": "<authorization>",
"Content-Type": "<content-type>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': '<content-type>'},
body: JSON.stringify({input: {}})
};
fetch('https://your-sutro-deployment.example.com/v1/functions/{name}/run', 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://your-sutro-deployment.example.com/v1/functions/{name}/run",
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([
'input' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: <content-type>"
],
]);
$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://your-sutro-deployment.example.com/v1/functions/{name}/run"
payload := strings.NewReader("{\n \"input\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "<content-type>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://your-sutro-deployment.example.com/v1/functions/{name}/run")
.header("Authorization", "<authorization>")
.header("Content-Type", "<content-type>")
.body("{\n \"input\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-sutro-deployment.example.com/v1/functions/{name}/run")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = '<content-type>'
request.body = "{\n \"input\": {}\n}"
response = http.request(request)
puts response.read_body{
"request_id": "<string>",
"function": {},
"output": {},
"confidence": 123,
"usage": {}
}API
Run a Function in real time
Execute a published Function on one input and wait for the answer.
POST
/
v1
/
functions
/
{name}
/
run
Run a Function in real time
curl --request POST \
--url https://your-sutro-deployment.example.com/v1/functions/{name}/run \
--header 'Authorization: <authorization>' \
--header 'Content-Type: <content-type>' \
--data '{
"input": {}
}'import requests
url = "https://your-sutro-deployment.example.com/v1/functions/{name}/run"
payload = { "input": {} }
headers = {
"Authorization": "<authorization>",
"Content-Type": "<content-type>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': '<content-type>'},
body: JSON.stringify({input: {}})
};
fetch('https://your-sutro-deployment.example.com/v1/functions/{name}/run', 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://your-sutro-deployment.example.com/v1/functions/{name}/run",
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([
'input' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: <content-type>"
],
]);
$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://your-sutro-deployment.example.com/v1/functions/{name}/run"
payload := strings.NewReader("{\n \"input\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "<content-type>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://your-sutro-deployment.example.com/v1/functions/{name}/run")
.header("Authorization", "<authorization>")
.header("Content-Type", "<content-type>")
.body("{\n \"input\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-sutro-deployment.example.com/v1/functions/{name}/run")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = '<content-type>'
request.body = "{\n \"input\": {}\n}"
response = http.request(request)
puts response.read_body{
"request_id": "<string>",
"function": {},
"output": {},
"confidence": 123,
"usage": {}
}Run a published Function on a single input and receive the answer in the
response. The Function supplies its optimized prompt, model, output schema, and
sampling defaults; none of them can be overridden per request. Use
Batch instead for tables of inputs.
Configure your deployment URL and API key before
using the examples below. Use the deployment where you published the Function.
PNG, JPEG, WebP, and PDF are accepted, up to 20 MB per asset. The bytes are
sniffed, so a declared
Every successful answer is also recorded in the Function’s Monitoring
tab, and low-confidence answers are added to Needs Review.
Deployment operators can change these defaults with the
Requests are never retried automatically: a Function run costs tokens, and a
caller waiting on an answer should decide for itself whether to try again.
The Python SDK wraps this endpoint as
string
required
The published Function name, without a namespace or revision.
Headers
string
required
Deployment API key in the form
Key YOUR_SUTRO_API_KEY.string
required
application/json. The body is limited to 32 MB.Body
object | string
required
The Function’s input fields. Keys must match the Function’s configured inputs; every field is required and unknown fields are rejected. Values that are not strings are converted the same way Batch converts a row:
null becomes an empty string, objects and lists become JSON, and anything else becomes its plain string form. A bare string is accepted in place of the object when the Function has exactly one text input. Image and PDF fields take an asset value.input is the only accepted field. Any other field returns 422 invalid_input.
Run a published Function
curl --fail-with-body "${SUTRO_API_URL%/}/v1/functions/support-escalation/run" \
-H "Authorization: Key $SUTRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {"text": "The customer reports an unrecognized charge."}
}'
Image and PDF inputs
An image or PDF input field takes one of three values.| Value | Shape |
|---|---|
| Inline bytes | {"base64": "...", "mime_type": "image/png"} |
| URL | {"url": "https://..."}. https only, public hosts only (no private, loopback, or link-local addresses), streamed with a 10 second timeout. |
| Stored asset | {"name": "march-invoice.pdf"}, or the name as a bare string. |
curl --fail-with-body "${SUTRO_API_URL%/}/v1/functions/invoice-reader/run" \
-H "Authorization: Key $SUTRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"note": "check page 2",
"scan": {"base64": "JVBERi0...", "mime_type": "application/pdf"},
"logo": {"url": "https://cdn.example.com/logo.png"},
"prior": {"name": "march-invoice.pdf"}
}
}'
type or mime_type that disagrees with the actual
content is rejected rather than passed to the model.
Response
{
"request_id": "rt_01j7wnq3f8k2c9x4",
"function": {
"name": "support-escalation",
"model": "claude-sonnet-4-5",
"model_source": "model-sweep"
},
"output": {"label": "billing", "reasoning": "..."},
"confidence": 0.8,
"usage": {"input_tokens": 412, "output_tokens": 38, "cost_usd": 0.0016}
}
string
This request’s ID. It also appears in the Function’s Monitoring tab and in every error body, for log and support lookups.
object
The Function that answered: its
name, the base model, and model_source. model_source is model-sweep when a model was set active from a model sweep, or sutro-default when the Function ran its latest iteration’s prompt on the Sutro default model.object | string
The answer, parsed against the Function’s output schema. A string when the Function has no schema.
number
A confidence score between 0 and 1 for this answer, computed the same way as in Batch. Answers at or below
0.6 are the ones worth a human look. See confidence scores.object
input_tokens, output_tokens, and cost_usd for the whole request.Limits
| Limit | Default |
|---|---|
| Requests per API key | 10 per second, bursting to 20 |
| In-flight requests per model | 64 per deployment |
| Request timeout | 90 seconds |
| Input size | 200,000 characters, counted after the input fields are joined into the prompt the model receives |
| Asset size | 20 MB each |
| Request body | 32 MB |
HARMONIZE_REALTIME_*
environment variables.
Errors
Failures return{"detail": ..., "code": ..., "request_id": ...}. A 429 or
503 that can be retried carries a Retry-After header with the number of
seconds to wait.
| Status | code | Cause |
|---|---|---|
| 401 | unauthorized | Missing or invalid API key. |
| 404 | function_not_found | No Function by that name in this deployment. |
| 409 | no_runnable_prompt | The Function has no published or completed prompt to run yet. |
| 409 | deployment_unpublished | The latest deploy or completed iteration failed to publish to Batch, so real time refuses to serve a prompt Batch does not. Retry the publish. |
| 413 | payload_too_large | The request body is over 32 MB. |
| 422 | invalid_input | Malformed body, a field other than input, missing, unknown, or oversized input, or an unreadable asset. |
| 422 | not_servable | The Function’s active model cannot serve it in real time. The message says why. |
| 429 | rate_limited | Your key’s request rate. See Retry-After. |
| 429 | at_capacity | The deployment has no room for another request on this model right now. Retry after Retry-After. |
| 429 | provider_rate_limited | The model provider rate limited the request. See Retry-After. |
| 502 | provider_error | The model provider failed or returned an unusable answer. |
| 503 | auth_unavailable | The deployment could not verify the API key. Retry. |
| 503 | provider_not_configured | No API key is configured for the Function’s provider. Add one in the app’s provider settings. |
| 503 | inference_spend_circuit_open | The deployment’s paid-inference budget is paused. See Retry-After. |
| 504 | timeout | The request exceeded the 90 second budget. |
run_function().