> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sutro.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Run a Function in real time

> Execute a published Function on one input and wait for the answer.

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](/reference/api/running-batch-inference) instead for tables of inputs.

Configure your [deployment URL and API key](/reference/authentication) before
using the examples below. Use the deployment where you published the Function.

<ParamField path="name" type="string" required>
  The published Function name, without a namespace or revision.
</ParamField>

## Headers

<ParamField header="Authorization" type="string" required>
  Deployment API key in the form `Key YOUR_SUTRO_API_KEY`.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  `application/json`. The body is limited to 32 MB.
</ParamField>

## Body

<ParamField body="input" type="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](#image-and-pdf-inputs).
</ParamField>

`input` is the only accepted field. Any other field returns `422 invalid_input`.

## Run a published Function

```bash theme={null}
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.                                                                                |

```bash theme={null}
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"}
    }
  }'
```

PNG, JPEG, WebP, and PDF are accepted, up to 20 MB per asset. The bytes are
sniffed, so a declared `type` or `mime_type` that disagrees with the actual
content is rejected rather than passed to the model.

## Response

```json theme={null}
{
  "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}
}
```

<ResponseField name="request_id" type="string">
  This request's ID. It also appears in the Function's **Monitoring** tab and in every error body, for log and support lookups.
</ResponseField>

<ResponseField name="function" type="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.
</ResponseField>

<ResponseField name="output" type="object | string">
  The answer, parsed against the Function's output schema. A string when the Function has no schema.
</ResponseField>

<ResponseField name="confidence" type="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](/functions/run#confidence-scores).
</ResponseField>

<ResponseField name="usage" type="object">
  `input_tokens`, `output_tokens`, and `cost_usd` for the whole request.
</ResponseField>

Every successful answer is also recorded in the Function's **Monitoring**
tab, and low-confidence answers are added to **Needs Review**.

## 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                                                                                            |

Deployment operators can change these defaults with the `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.                                                                                                     |

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](/reference/python-sdk/run-function) wraps this endpoint as
`run_function()`.
