Spring Boot webhook failing to update Cognigy dialog context after LLM tool execution

Running into a wall with the Cognigy.AI webhook integration. We’re simulating function calling by catching the LLM output JSON, routing it to a Java Spring Boot service, and feeding the results back into the dialog context. The parsing side works fine with Jackson, but the PUT request to update the session keeps dropping with a 400 Bad Request. The payload structure seems to match the docs, yet the platform rejects the variables array formatting.

Here’s what the webhook receives from Cognigy:

{
 "toolCalls": [{"function": "checkBalance", "arguments": {"accountId": "8842"}}],
 "sessionId": "sess_9f8a2c1d",
 "flowId": "f_1234"
}

The Spring endpoint processes the checkBalance call against our internal ledger service. When we try to push the result back, it’s hitting this:

PUT /api/v2/sessions/sess_9f8a2c1d/variables
Content-Type: application/json

[
 {"name": "balanceResult", "value": {"status": "success", "amount": 1250.50}},
 {"name": "toolCallComplete", "value": true}
]

The response just throws a generic validation error on the value field. Cognigy expects primitive types or specific object wrappers, but the schema isn’t explicitly documented for dynamic tool returns. We’ve tried wrapping the object in a JSON string, flattening it to key-value pairs, and even switching to the context endpoint instead of variables. Nothing sticks. The async pipeline is solid, but the contract between the LLM output and the Cognigy variable schema is completely opaque.

  • Spring Boot 3.2 with WebFlux
  • Cognigy.AI Runtime v4.8
  • Jackson 2.16 for JSON serialization
  • Tried explicit @RequestBody List<Map<String, Object>> binding
  • Verified OAuth token has session:write scope
  • Added Accept: application/json header to the client

The Tokio event loop we use for the Genesys WebSocket side handles backpressure perfectly, so this isn’t a throughput issue. Just a payload mismatch. Staring at the 400 response body for the third hour straight.