Bot conversation API returning 400 BAD REQUEST on `/api/v2/conversations/botsessions` with missing intent payload

The .NET SDK version 2023.11.0 keeps dropping the intent field when pushing bot session data to our internal CRM webhook. Docs state: “Bot session payloads must include a valid intent object to trigger the Architect decision tree.” Why does the serializer strip the required data? The payload looks fine in Fiddler, but the Azure Function returns a 400 BAD REQUEST every time. Console is empty. The routing engine just times out after 12 seconds. The PostConversationsBotSessionsAsync method uses a standard BotSessionRequest model. The serializer strips the nested entities array because it’s marked as optional in the OpenAPI spec. You’ll need to force a non-nullable type, but the SDK generator ignores that flag. The flow in Architect expects the intent to match order_status_check, yet the webhook receives null for the whole intent block. Doing jack all on the retry policy since the payload never hits the second stage.

Docs state: “Intent validation requires explicit schema matching before the handoff event fires.” The JSON matches the example in the developer portal exactly. Only the confidence score gets truncated to two decimals by the default formatter. Architect flow ID bot_9f8a7c shows the handoff node as green, but the API response logs a SCHEMA_MISMATCH error. The HttpClient pipeline handles the Bearer token just fine, authentication isn’t the blocker here. Rate limits are sitting at 12/50 requests per minute. The webhook URL is verified in the integrations tab. Still getting the same 400 response when the bot tries to push the transcript. Error payload returns: {“code”:“BAD_REQUEST”,“message”:“Intent payload missing required fields”,“details”:“Schema validation failed at path $.intent.entities”}

The genesys-cloud-sdk-dotnet library handles property serialization differently when the BotSession object gets passed through the Proxy. It doesn’t preserve nested objects that aren’t explicitly marked with [JsonProperty] in the 2023.11.0 build. This exact behavior shows up when pushing session data to external endpoints. Console stays empty. The routing engine just times out after 12 seconds. Fiddler shows the drop right before the outbound call.

Here is what was tested:

  • Sent raw JSON payload directly via cURL. The 400 error disappeared. The intent object reached the Azure Function correctly.
  • Used the SDK CreateBotSession method with default serializer settings. The intent field vanished from the outgoing request.
  • Checked the Fiddler trace again. The SDK converts the intent dictionary to an empty array instead of an object structure.

The fix requires overriding the default serialization contract resolver. You’ll need to force the SDK to preserve the intent payload by attaching a custom JsonSerializerSettings object to the ApiClient.

var settings = new JsonSerializerSettings {
 NullValueHandling = NullValueHandling.Ignore,
 ContractResolver = new DefaultContractResolver()
};
client.SetJsonSerializerSettings(settings);

handles raw JSON strings better than deserialized SDK models for this specific endpoint anyway. Building the payload manually inside the action bypasses the serializer entirely. It’s usually faster to skip the SDK model mapping when the external webhook expects a strict schema.

{
 "conversationId": "{{conversation.id}}",
 "intent": {
 "name": "primary_routing_intent",
 "confidence": 0.95
 }
}

Check the schema validation on the Azure Function. Does it strictly require the confidence key, or will it accept a plain string for the name property?

The proxy serialization drop is exactly what breaks the downstream analytics pipeline. Here is the test log.

  • Forced intent through PostConversationsBotSessions in PureCloudPlatformClientV2. Failed with 400.
  • Swapped to raw HttpClient call with conversation:bot:write scope. Still stripped.
  • Added explicit JSON annotation. Payload finally hits /api/v2/conversations/botsessions intact.
[JsonProperty("intent", NullValueHandling = NullValueHandling.Ignore)]
public BotIntent IntentData { get; set; }

Ran it through the staging tenant. It’s frustrating how the SDK team keeps shipping broken serializers. You’ll want to bypass the default proxy handler. Don’t let the wrapper touch the nested objects. What version of Newtonsoft.Json are you locking to in the project file. The default build ignores custom attributes. Check your package config.