Skip to content

API reference

Analyze a selected piece of assistant output against its recorded conversation. Strahl provides two endpoints:

  • Attributions: high-level attribution endpoint that identifies the most influential sequences and groups them into excerpts ranked by influence, with the specific influential phrases highlighted.
  • Attribution scores: a low-level attribution endpoint that returns precise influence scores for character spans in the original transcript.

For a guided introduction, start with the quickstart.

POST https://strahl.ai/api/v1/attributions
Authorization: Bearer <API_KEY>
Content-Type: application/json

Send the recorded conversation, including the assistant output you want to investigate. Each request selects one assistant field and, for text or tool arguments, a character range within it. Preserve the original strings and message order.

{
"input": {
"format": "openai/v1/chat/completions",
"data": {
"messages": [
{ "role": "user", "content": "The access code is 1234." },
{ "role": "assistant", "content": "The code is 1234." }
]
},
"target": {
"ref": { "message_index": 1, "field": "content" },
"span": { "start": 12, "end": 16 }
}
}
}

This selects 1234 in the assistant’s answer. Message indexes start at zero; [12, 16) includes characters 12 through 15.

Wrap these fields in the top-level input object:

Field Required Description
input.format Yes Use the exact string openai/v1/chat/completions.
input.data.messages Yes A nonempty array of messages in Chat Completions format, including the assistant output to analyze.
input.data.tools No Tool definitions from the recorded conversation, when available.
input.target Yes The assistant field and text range to analyze. See target fields for references and offsets.

Provide the message array under input.data.messages; a provider response’s choices array is not accepted. Unknown fields in the request envelope, input, data, target, reference, and span objects are rejected. Extra provider metadata inside individual messages and tool definitions is ignored.

Targets must select a field belonging to an assistant message. All indexes start at zero; supply an index explicitly even when its value is 0.

refReferencerequired

Identifies an original field in input.data.messages.

message_indexintegerrequired

Zero-based index of the assistant message to analyze.

fieldstringrequired

Field identifier from the reference table.

content_indexintegeroptional

Required for content_text and content_refusal. Omit it for other fields.

tool_call_indexintegeroptional

Required for modern function/custom tool-call fields. Omit it for other fields.

spanobjectoptional

Required for text, refusals, tool arguments, and custom input. Omit it only when selecting a whole tool-call name. Use a nonempty half-open range [start, end) in the original decoded string.

startintegerrequired

Inclusive Unicode code-point offset, starting at zero.

endintegerrequired

Exclusive Unicode code-point offset, greater than start and no larger than the field’s length.

The same reference shape is used in returned evidence. Returned references may point to source messages rather than the assistant target.

field Original string Additional index
content messages[i].content (string) None
content_text messages[i].content[j].text content_index
content_refusal messages[i].content[j].refusal content_index
refusal messages[i].refusal None
function_name messages[i].tool_calls[j].function.name tool_call_index
function_arguments messages[i].tool_calls[j].function.arguments tool_call_index
custom_name messages[i].tool_calls[j].custom.name tool_call_index
custom_input messages[i].tool_calls[j].custom.input tool_call_index
legacy_function_name messages[i].function_call.name None
legacy_function_arguments messages[i].function_call.arguments None

Offsets count Unicode code points, not bytes or JavaScript UTF-16 code units. For example, A🙂B has three code points. In JavaScript, use Array.from(text) when calculating or slicing API ranges. Python string indexes already use code points.

A successful request returns HTTP 200 with analysis metadata and ranked excerpts.

analysis_profilestringrequired

Identifier for the analysis configuration.

extraction_profilestringrequired

Identifier for the policy used to select and rank excerpts.

effective_spanobjectrequired

The analyzed start and end in the selected original field. Token boundaries can expand the requested span or contract coverage over unmapped whitespace.

prompt_tokensintegerrequired

Token count of the submitted conversation after formatting for analysis.

excerptsExcerpt[]required

All qualifying passages, ranked by influence, from user, tool, and legacy function-result message text. System/developer text, assistant text, tool-call fields, and tool definitions are excluded from excerpt selection, though they remain in the analysis input. An empty array means no eligible passages were selected.

refReferencerequired

Location of the original source field. Uses the reference fields.

startintegerrequired

Inclusive Unicode code-point offset in the source field.

endintegerrequired

Exclusive Unicode code-point offset in the source field.

textstringrequired

Exact source text between start and end, including whitespace.

scorenumberrequired

The attribution score of the excerpt’s most influential fragment.

relative_scorenumberrequired

Attribution score relative to the strongest source in this result.

highlightsHighlight[]required

The specific phrases identified as influential to the selected output. These phrases are grouped into excerpts with surrounding text to provide context. Each highlight has start, end, text, score, and relative_score. Ranges address the original source field, not the excerpt substring. Highlights inherit the excerpt’s ref.

{
"analysis_profile": "<analysis-profile>",
"extraction_profile": "<extraction-profile>",
"effective_span": { "start": 12, "end": 16 },
"prompt_tokens": 32,
"excerpts": [
{
"ref": { "message_index": 0, "field": "content" },
"start": 0,
"end": 24,
"text": "The access code is 1234.",
"score": 0.42,
"relative_score": 1,
"highlights": [
{
"start": 19,
"end": 23,
"text": "1234",
"score": 0.42,
"relative_score": 1
}
]
}
]
}

An excerpt may contain surrounding text that is not highlighted. Inspect its highlights and original context before making a claim about influence.

POST https://strahl.ai/api/v1/attributions/scores
Authorization: Bearer <API_KEY>
Content-Type: application/json

Use this low-level API to work directly with influence scores for character spans. It accepts the same input object as the attributions endpoint.

A successful request returns HTTP 200 with analysis metadata and scored source spans. Each source points to a character range in the original transcript.

analysis_profilestringrequired

Identifier for the analysis configuration.

effective_spanobjectrequired

The analyzed start and end in the selected original field. Token boundaries can expand the requested span or contract coverage over unmapped whitespace.

prompt_tokensintegerrequired

Token count of the submitted conversation after formatting for analysis.

sourcesSource[]required

All eligible source spans before the target and their influence scores, including low and zero scores.

refReferencerequired

Location of the original source field. Uses the reference fields.

startintegerrequired

Inclusive Unicode code-point offset in the source field.

endintegerrequired

Exclusive Unicode code-point offset in the source field.

scorenumberrequired

The attribution score for this character span.

{
"analysis_profile": "<analysis-profile>",
"effective_span": { "start": 12, "end": 16 },
"prompt_tokens": 32,
"sources": [
{ "ref": { "message_index": 0, "field": "content" }, "start": 0, "end": 3, "score": 0.01 },
{ "ref": { "message_index": 0, "field": "content" }, "start": 3, "end": 10, "score": 0.02 },
{ "ref": { "message_index": 0, "field": "content" }, "start": 10, "end": 15, "score": 0.03 },
{ "ref": { "message_index": 0, "field": "content" }, "start": 15, "end": 18, "score": 0.01 },
{ "ref": { "message_index": 0, "field": "content" }, "start": 18, "end": 19, "score": 0 },
{ "ref": { "message_index": 0, "field": "content" }, "start": 19, "end": 20, "score": 0.42 },
{ "ref": { "message_index": 0, "field": "content" }, "start": 20, "end": 21, "score": 0.40 },
{ "ref": { "message_index": 0, "field": "content" }, "start": 21, "end": 22, "score": 0.41 },
{ "ref": { "message_index": 0, "field": "content" }, "start": 22, "end": 23, "score": 0.39 },
{ "ref": { "message_index": 0, "field": "content" }, "start": 23, "end": 24, "score": 0.001 },
{ "ref": { "message_index": 1, "field": "content" }, "start": 0, "end": 3, "score": 0.01 },
{ "ref": { "message_index": 1, "field": "content" }, "start": 3, "end": 8, "score": 0.02 },
{ "ref": { "message_index": 1, "field": "content" }, "start": 8, "end": 11, "score": 0.01 },
{ "ref": { "message_index": 1, "field": "content" }, "start": 11, "end": 12, "score": 0 }
]
}

Errors use standard HTTP status codes with a JSON body describing what went wrong.

{ "error": { "message": "A valid API key is required." } }
Status Meaning
400 Bad Request Malformed JSON, unsupported input, invalid target, or input rejected by analysis
401 Unauthorized Missing, malformed, invalid, or revoked customer API key
402 Payment Required Available prepaid credits are insufficient for the maximum request reservation
408 Request Timeout The request was canceled
413 Content Too Large The complete JSON request exceeds 8 MiB
429 Too Many Requests The per-user request rate was exceeded
500 Internal Server Error An internal application failure
502 Bad Gateway An upstream computation failed
503 Service Unavailable Request capacity, key validation, billing, or analysis is unavailable
504 Gateway Timeout The request timed out

Rate-limit and capacity rejections include a Retry-After header in seconds. Use exponential backoff when retrying, waiting at least the indicated delay.