Skip to main content
This page covers the detailed configuration for Endpoint Connection request formatting, response extraction, retry behavior, and conversation end rules.

Input Template

The Input Template is a Jinja2 template string that defines how Galtea formats the request body before sending it to your endpoint.
For a detailed guide on structured input syntax ({{ input.field_name }}), context fields, JSON escaping, the placeholder toolbar, and missing field behavior, see the Structured Input Template Syntax reference.

Available Placeholders

{{ trace_id }} and {{ dataset_id }} were named {{ inference_result_id }} and {{ test_id }} before version 5.0.0, and the old names still resolve. See Dataset, Trace, and Span Renames.

Conversation History

Use {% for turn in past_turns %}...{% endfor %} to loop through previous conversation turns. Each turn exposes:
  • {{ turn.input }} — Previous user input
  • {{ turn.output }} — Previous assistant response

Attached Files

Use {{ input_files[0].url }} to send an attached file to your endpoint, or {{ input_files[0].base64 }} to send its bytes inline. See Attached Files and Audio for the full rules, including the 15-minute URL lifetime.

Examples

OpenAI-compatible format:
Previous queries array:
Custom format:
When a loop is the last item in a JSON array, use {% if not loop.last %},{% endif %} after each iteration to prevent a trailing comma. When there’s content after the loop (like in the OpenAI example above), trailing commas are valid and this pattern is not required.

Output Mapping

A JSON object defining how to extract values from the API response using JSONPath expressions.

Special Keys

JSONPath Syntax Reference

Example

Files in the Response

Use the output_files key when your agent answers with a document: a generated report, a filled form, an image. Galtea stores a copy of each file on the turn’s output, so a later read always sees the same bytes. A file that is already in Galtea is linked instead of copied. The stored files appear as the trace’s Output Files. Each file the path matches can take one of three forms:
  • Bytes: an object with base64 and optional mime_type and filename, or a data: URI string. The standard and the URL-safe base64 alphabets both work. Galtea decodes the bytes and makes no extra request.
  • URL: an http(s) URL string, or an object with url (or uri) and optional mime_type and filename. Galtea downloads the file once, during the run.
  • Galtea file: the storage URI of a file already uploaded to Galtea, as a string or in url or uri. It is the signature-free uri a written trace or test case reads back with, as stored or under the deployment’s public file base when one is set. Galtea links the file on the turn, with no download and no copy. A signed link is a URL, not a Galtea file: it is downloaded and copied. That covers the uri an SDK upload returns and the url of an input_files item.
The text still comes from output. A response with files and no text is also a valid turn. An empty value (null, [], {} or an empty string) means the turn has no file. The rules:
  • Limits: at most 20 files and 20 MB in total for one output, Galtea files included. The file extension decides the type, and it must be one a test case input accepts, such as pdf, docx, png or csv. A file with no extension takes one from its mime_type, or, for a URL, from the Content-Type the file host sends. A name that ends in digits only, such as invoice_2026.09.23, counts as having no extension.
  • Download time: all the URL downloads of one output share one time limit, the connection’s timeout. A URL file that has not started when that time runs out is refused.
  • No credentials to the file host: Galtea sends none of the connection’s headers or credentials with the download. A file that needs authentication must come back as bytes, or as a presigned URL that carries its own access.
  • Galtea files belong to your organization: a Galtea file must be an uploaded file of the organization that owns the product. A file of another organization, or a storage URI that does not name an uploaded file, fails the turn. The same holds for a file that no longer exists.
  • Plain HTTP: an http:// file URL is downloaded only when the connection acknowledged plain HTTP, or the deployment allows it for every connection (see HTTP endpoints). Private and internal addresses, such as loopback and cloud metadata, are refused, as they are for the endpoint itself.
  • A refused file fails the turn: the error names the file and the reason, for example Output file refused: file 2 ("setup.exe"): the type ".exe" is not allowed. Galtea stores no file of that turn. When the check Galtea makes before a run already receives a file it would refuse, the run is rejected before it starts.
  • Single-turn runs only: as with file inputs, a run of more than one turn fails the turn whose response carries a file. The simulated user reads text only, so the conversation would go on as if the agent said nothing. Run the test case as a single turn, or remove output_files from the mapping.
  • Conversation connections only: Initialization and Finalization connections ignore output_files.
The Test Connection panel lists the files it finds and shows why a file would be refused. It previews a bytes file and a Galtea file, and it never downloads a URL file. It refuses a Galtea file of another organization, but a Galtea file that no longer exists fails only when a run reads it.
Evaluators cannot read output files yet. A metric that reads the output is skipped unless at least one turn of the session has text and no file. Text sent beside a file does not count, so a single-turn run whose answer carries a file always skips it. See Output Files.

State Management

If your API returns values that need to be sent in subsequent requests (e.g., session_id, tenant_id), Galtea can automatically manage this state:
  1. Extract — Use Output Mapping to pull values from the API response using JSONPath expressions
  2. Store — Extracted values are saved in the session and become available as template variables
  3. Reuse — Reference any stored value in the Input Template or URL using {{ variable_name }} syntax
On the first turn, undefined placeholders resolve to empty strings. After the first response, all extracted values become available for subsequent turns.
Example: capture session_id and tenant_id from responses:

Custom Headers

Custom headers are sent with every request to your endpoint. Header values support placeholder substitution. You can inject authentication credentials, so you can place tokens in any header, not just the standard Authorization or X-API-Key headers. You can also inject ids of the current call, such as the session ID or the Galtea Trace ID.

Available Placeholders

Placeholders are case-insensitive and work with both {{ placeholder }} and { placeholder } syntax. Galtea renders all placeholders of a header value in one pass. A value that does not exist yet renders as an empty string. For example, {{ session_id }} is empty until your endpoint returns a session ID. A rendered value is never scanned for placeholders again. Which context placeholders hold a value depends on the call: Every other context placeholder renders empty in that call.
Header values carry Latin-1 characters only. A value with other characters, for example a session_id that holds them, fails the call. A value with a line break fails the call too.

Example

If you define an Authorization or X-API-Key header in custom headers, Galtea will not add the default authentication header — your custom header takes precedence.

Secret Header Values

Galtea treats a header value as a secret unless one of these is true:
  • The header name is Content-Type, Accept, Accept-Language, Accept-Encoding, Cache-Control, User-Agent, traceparent, or tracestate.
  • The value holds only placeholders, with an optional Bearer, Basic, or Token prefix (for example Bearer {{ bearer_token }}).
Galtea encrypts each secret value when you save the connection, and sends the real value to your endpoint. The Dashboard, the API, the SDK, and the CLI show a secret value as ••••••••. A test of a saved connection sends its stored secrets to the URL of the test, and returns what that URL answers. So every test of a saved connection needs permission to edit it, for any URL. A member who can only view the connection gets a 403 error. A member who can edit the connection can change its URL, so give edit permission only to people you trust with its secrets. In the example above, only X-Tenant-Id is a secret. A header imported from a cURL command, such as CF-Access-Client-Secret, is a secret too. To change a connection’s headers, send the whole map again:
  • Keep •••••••• as the value of a header to keep its stored value.
  • Type a new value to replace it.
  • Remove the header to delete it.
A •••••••• value for a header that has no stored value is rejected with a 400 error. An encrypted value is also rejected with a 400 error: send the plain value instead. So is a value that only looks like ••••••••, such as ••••••••abc: keep the exact value, or type the whole new one.

W3C Trace Context Propagation

Galtea sends a traceparent header on every conversation turn call, following the W3C Trace Context specification. It does this whether or not the platform’s own tracing is on, and on every retry of the turn. You do not need to set anything up. Your endpoint can correlate its spans with the turn without any code changes.
  • Each turn has one trace ID. Every retry of the turn sends the same trace ID.
  • Galtea stores the trace ID on the turn when the turn starts, before it calls your endpoint. A span your agent exports before it answers attaches to the turn.
  • Galtea never sends the header on initialization, finalization, or test-connection calls.
  • Galtea sets the header itself. Galtea refuses a traceparent header in custom headers on save (400).
The header is flagged as sampled. An agent with a parent-based sampler records every Galtea test call, so expect more trace volume in your own tracing backend.
See Send OpenTelemetry Traces to Galtea for how correlated spans become Span records.

Baggage

Galtea also sends a W3C baggage header on every conversation turn call:
The value is the id of the turn, the same one as {{ trace_id }}. If you set your own baggage header, Galtea merges its member into yours. Your other members stay. A galtea.trace.id member you set is replaced. An agent that copies baggage onto its spans attaches every span to the turn, even when a proxy or gateway starts a new trace and changes the trace ID. To copy baggage onto spans, use the OpenTelemetry baggage span processor for Python or JavaScript. Both accept a key predicate. Use one that copies only keys that start with galtea..
An agent instrumented with OpenTelemetry forwards baggage to every service it calls, including LLM providers and other third parties. So the turn id can leave your agent. The id is opaque: nobody can read or write anything with it without a Galtea API key of your organization.
Python OpenTelemetry drops a baggage header longer than 8192 characters. Galtea’s member adds about 60 characters, so keep your own baggage well below that limit.

Timeout

How long Galtea waits for a single HTTP call to your endpoint before giving up. It is applied per attempt, so each retry gets the full timeout again.
Number
Per-attempt request timeout in seconds. Default: 15. Maximum: 120 (values above this are rejected at the API).
A timeout counts as a retryable failure. If retry is enabled, a timed-out call is retried like any other transient error.

Rate Limit

The maximum number of requests per minute your backend can handle. Galtea throttles itself to stay under this limit, using a token bucket shared across all of Galtea, so the limit holds even when many runs execute at once.
Number
Maximum requests per minute. Default: empty, which means no limit (no throttling). Set a number only if your backend needs Galtea to slow down.
When the limit is reached, Galtea reschedules the call for later. This wait does not use up a retry attempt and does not block other runs.

Retry Configuration

Configure automatic retry behavior for failed requests. When enabled, Galtea retries requests that fail with a retryable HTTP status code, a timeout, or a network error. A retry wait does not block other runs: the job is rescheduled and the worker is freed while it waits.
Boolean
Whether automatic retry is enabled. Default: true
Number
Maximum number of retry attempts (0-10). Default: 1. These are retries after the first call, so N attempts means up to N+1 calls to your endpoint, and each call uses credits (the default of 1 means up to 2 calls). 0 is only valid when retry is disabled; with retry enabled the minimum is 1.
Number
Initial delay in milliseconds before the first retry. Default: 1000 (1 second)
Enum
Strategy for increasing delay between retry attempts:
  • exponential - Delay doubles with each attempt (recommended)
  • linear - Delay increases linearly
  • fixed - Constant delay between attempts
Default: exponentialThe delay is always capped at Max Delay. With a small Max Delay, exponential and linear growth are clamped to that ceiling after the first retry, so the strategy has little effect. Raise Max Delay to let the delay grow.
Number
Maximum delay between retry attempts, in milliseconds. Default: 3000 (3 seconds). Capped at 60000 (60 seconds); values above this are rejected at the API.
Array of Numbers
HTTP status codes that should trigger a retry. Default: [429, 500, 502, 503, 504]. Each value must be a valid HTTP status code (100-599).Codes are honored literally with no client-error short-circuit. Adding a deterministic 4xx code (such as 401, 403, or 422) makes Galtea retry a call that will always fail, which wastes the full retry budget and the credits for each attempt.

Conversation End Rules

Some agents end a conversation on their own and then answer every further message with an error. Without a rule, Galtea reads that error as a failed turn, so the session fails. Its evaluations are then skipped because of the failed turn. A conversation end rule tells Galtea which reply means “the agent ended the conversation”. On a match, the session completes with the turns so far and is evaluated. A rule has a status code and an optional body match. Default: no rules. A connection holds at most 20 rules, and only a CONVERSATION connection accepts them.
Number
HTTP status code of the reply (100-599). A 2xx code needs a body match, because a 2xx rule without one would end the conversation after the first normal reply.
Text
Optional. A JSONPath into the response body, starting with $ (for example $.error.code). See JSONPath Syntax Reference. Filter expressions such as [?(...)] are refused.
Text
Used when a Body JSONPath is set. The first value the path finds must equal this text. An empty Expected Value matches an empty string.

Example

After your agent closes the conversation, it answers every further message with HTTP 409 and this body:
The rule is status code 409, Body JSONPath $.error.code, and Expected Value conversation_ended. A 409 with any other error.code does not match, so it still fails the turn as before.

How a reply matches

  • Galtea checks the rules before the retry policy. A matching reply is never retried, even when its status code is in Retryable Status Codes.
  • A reply matches when the status code is equal and, if the rule has a body match, the first value the JSONPath finds is a string, number, or boolean whose text equals the Expected Value. So the number 42 matches the Expected Value 42.
  • A missing field, an object, an array, null, or a body that is not JSON never matches.
  • Rules apply only to the conversation calls of text sessions. Initialization and finalization calls, voice sessions, and the connection test ignore them.

What happens to the session

  • A 2xx match with an agent answer: the reply is a normal agent reply, so that turn stays as the last turn and is scored. This also holds on the first turn and in a single-turn test.
  • A match with no agent answer: a non-2xx match (such as the 409 above), or a 2xx match whose reply has no output. The rejected turn holds the simulated user message and no agent reply. Galtea removes that turn, so it is not scored.
  • In both cases the session completes with the stopping reason The agent ended the conversation (HTTP <code>), for example The agent ended the conversation (HTTP 409), and is evaluated.
  • A match with no agent answer on the first turn, or in a single-turn test, still fails the session, because there is no conversation left to evaluate.

Structured Input Template Syntax

Deep dive into {{ input.field_name }} and {{ context.field_name }} placeholder syntax, JSON escaping, and missing field behavior.

Endpoint Connection Overview

What endpoint connections are and how to create one.

Input Schema

Define structured, multi-field inputs for test case generation.

Direct Inferences Tutorial

Run evaluations from the dashboard using your endpoint connection.