Skip to Content
DocsEndpointsResponse Mapping

Response Mapping

Response mappings tell Rhesis how to extract platform variables from your API’s response. Each field is evaluated independently using JSONPath, Jinja2, or both.

JSONPath Expressions

Expressions starting with $ are evaluated as JSONPath against the response body:

jsonpath-response.json
{
  "output": "$.choices[0].message.content",
  "model_used": "$.model",
  "tokens": "$.usage.total_tokens"
}

Common patterns:

PatternDescription
$.fieldTop-level field
$.nested.fieldNested field
$.array[0].fieldField from first array element
$.data[*].texttext field from all array elements

Jinja2 with jsonpath()

For conditional logic or fallback values, wrap expressions in Jinja2:

jinja2-response.json
{
  "output": "{{ jsonpath('$.text_response') or jsonpath('$.result.content') }}",
  "conversation_id": "$.conversation_id"
}

Returns the first non-empty value. Pure JSONPath expressions (starting with $) work without any Jinja2 wrapping.

Mixing Approaches

Each field is evaluated independently — you can mix JSONPath and Jinja2 in the same mapping:

mixed-response.json
{
  "output": "$.response.text",
  "context": "{{ jsonpath('$.sources') or jsonpath('$.references') }}",
  "metadata": "{{ {'model': jsonpath('$.model_info.name'), 'latency_ms': jsonpath('$.timing.total_ms')} }}"
}

Platform-Managed Fields

output must always be mapped. Without it, Rhesis cannot evaluate responses against metrics.

Actively used by Rhesis:

  • output — main response text, used for metric evaluation
  • context — additional context, used by context-dependent metrics
  • Conversation tracking fields (conversation_id, session_id, thread_id, etc.) — used for multi-turn conversation management

Stored and available to metrics:

  • metadata — stored with the test result, available to custom metrics
  • tool_calls — stored with the test result, available to metrics that evaluate tool use

Custom fields beyond these are passed through and stored but not actively used by the platform.

SDK endpoint return values

For SDK connection-type endpoints, response mapping is applied only when the decorated function returns a dictionary. If the function returns a string, list, or another non-dictionary value, Rhesis skips the configured response mapping and wraps the value as output.

sdk_endpoint_return.py
from rhesis.sdk import endpoint

@endpoint()
def search(input: str) -> list[str]:
    return ["first match", "second match"]

# Rhesis receives:
# {"output": ["first match", "second match"]}

Return a dictionary when you need response mapping to extract multiple fields:

sdk_endpoint_mapped_return.py
from rhesis.sdk import endpoint

@endpoint()
def chat(input: str) -> dict:
    return {
        "message": "Hello",
        "metadata": {"model": "demo"},
    }

Complete Example

Request headers:

example-headers.json
{
  "Authorization": "Bearer {{ auth_token }}",
  "Content-Type": "application/json"
}

Request body template:

example-request.json
{
  "model": "gpt-4",
  "messages": [
    {
      "role": "user",
      "content": "{{ input }}"
    }
  ],
  "temperature": 0.7,
  "max_tokens": 1024
}

Response mapping:

example-response.json
{
  "output": "$.choices[0].message.content",
  "metadata": "$.usage"
}

Next steps