Skip to content

Traces: Custom API

The Custom API parser is the simplest. It works for any system that isn’t n8n or Flowise, whether it’s built with LangChain, your own code, or any other framework.

{
"data": {
"text": "The AI responded with this message."
}
}

That’s it. Mibo extracts the response text from text and evaluates your semantic assertions against it.

The parser looks for text in this order:

  1. The path configured in Response Parsing (set in your endpoint configuration)
  2. Common keys: text, message, content, output, answer, response
  3. The entire response as a string (fallback)

So any of these work:

{ "text": "Hello!" }
{ "message": "Hello!" }
{ "content": "Hello!" }
{ "output": "Hello!" }
{ "answer": "Hello!" }
{ "response": "Hello!" }

If your API returns a nested structure, set the response path in your platform configuration (e.g., data.choices.0.message.content) and send the full response:

{
"data": {
"choices": [
{
"message": {
"content": "The actual response text"
}
}
]
}
}

If your AI system uses tools/functions, include them as tool_calls:

{
"data": {
"text": "I found flights to Madrid starting at $299.",
"tool_calls": [
{
"name": "search_flights",
"arguments": {
"origin": "NYC",
"destination": "Madrid",
"date": "2026-04-01"
}
},
{
"name": "format_results",
"arguments": {
"format": "summary",
"limit": 5
}
}
]
}
}

Each tool call needs:

  • name (string): the function/tool name
  • arguments (object): the input passed to the tool

If your system has multiple steps or nodes (like a pipeline or workflow), you can add node-level structure so node_call assertions work. Use each node name as a key mapping to an object with an output field:

{
"data": {
"Retrieve Documents": {
"output": { "count": 12, "source": "knowledge-base" },
"status": "success"
},
"AI Agent": {
"output": {
"text": "Based on the 12 documents retrieved..."
},
"status": "success",
"tools_called": [
{
"name": "search_kb",
"input": { "query": "pricing" },
"output": { "results": 12 }
}
]
}
}
}

You can then assert on specific nodes and their output values:

{
"target": "node_call",
"condition": "MUST_CALL",
"expected_name": "Retrieve Documents",
"expected_arguments": {
"count": { "matcher": "gte", "value": 1 }
}
}

The node names in your trace ("Retrieve Documents", "AI Agent") are the same names you reference in expected_name. Each node’s output becomes the data that expected_arguments checks against. You can also use expected_tool_calls on nodes that include a tools_called array.

Terminal window
curl -X POST "https://api.mibo-ai.com/public/traces" \
-H "Content-Type: application/json" \
-H "x-api-key: mibo_your_api_key" \
-d '{
"data": {
"text": "Your appointment has been scheduled for tomorrow at 9 AM.",
"tool_calls": [
{
"name": "create_booking",
"arguments": {
"date": "2026-03-09",
"time": "09:00",
"user_id": 12345
}
}
]
}
}'
Assertion typeWorks?What it checks
SemanticYesEvaluates extracted text
json_matchYesChecks fields in the data
response_regexYesMatches pattern against text
json_schemaYesValidates data structure
http_statusOnly if _http_status is in data
response_timeOnly if _metadata.duration_ms is in data
token_limitAutomatic if response includes a supported token format
node_callYesChecks node entries in trace data (requires node-level structure)
node_call + expected_argumentsYesChecks node output values (requires nodes with output keys)
node_call + expected_tool_callsYesChecks tool calls within a node (requires tools_called array)