Fix first: in your APIM instance, open the azure-openai-token-limit policy and set estimate-prompt-tokens to false. Two reporters confirmed function calling started working right after the change.

```text
400 unable to parse
```

1. Open the azure-openai-token-limit policy in Azure APIM.
2. Set estimate-prompt-tokens to false. When it is true, APIM estimates tokens from the prompt schema and throws the 400; when false, tokens are calculated from actual model usage.
3. Retry the function call. Expected: the call succeeds and returns tool calls with no 400.

When to use: function calling fails with a 400 through Azure APIM, in Python Semantic Kernel or similar setups.

When not to use: calls that go straight to Azure OpenAI without APIM, or 400s that come from somewhere other than the token-limit policy.

Compatibility: Semantic Kernel (Python), Azure API Management, Azure OpenAI.

Variants:
- "apim function calling 400 unable to parse"
- "azure-openai-token-limit policy function calling"
- "estimate-prompt-tokens false"

Root cause: with estimate-prompt-tokens set to true, APIM tries to estimate tokens from the function-calling prompt schema and fails to parse it, so the request is rejected before it ever reaches the model.

Edge cases: if other APIs on the same APIM instance depend on estimated tokens, scope the change to the function-calling API instead of flipping it globally.