Formerly known as Azure AI Services or Azure Cognitive Services is a unified collection of prebuilt AI capabilities within the Microsoft Foundry platform
Hello JustinD,
Welcome to the Microsoft Q&A and thank you for posting your questions here.
I understand that your Azure OpenAI Intermittent 400 Error: Item with id not found.
My best recommendation for you is to use stateful chaining with previous_response_id so that you minimize payload, have immune to ordering errors, and aligns with chaining responses together as in Azure docs. These are steps to do that:
- Call 1: Capture
response.idand find thefunction_callitem (bytype) and itscall_id, to send user input + tools. - Execute your tool locally.
- Call 2: Send only a
function_call_outputitem with the samecall_idandprevious_response_idset to the first call’sresponse.id. Do not resend prior items. - If the model returns more tool calls repeat step 3 for each
call_iduntil you receive the final message.
Check the below for your repro:
import requests, json
API_KEY = "..."
MODEL = "..."
RESOURCE_NAME = "..."
URL = f"https://{RESOURCE_NAME}.openai.azure.com/openai/v1/responses"
HEADERS = {
"content-type": "application/json",
"accept": "application/json",
"api-key": API_KEY,
}
def stateful_round_trip():
# 1) First call – let the model decide to call a tool
payload1 = {
"model": MODEL,
"instructions": "You are a friendly agent that always calls a tool. Output the result of the tool.",
"input": [{ "role": "user", "content": "Wonder what the tool call returns" }],
"tools": [{
"type": "function",
"name": "myToolCall",
"description": "Tool to Call",
"parameters": {
"type": "object",
"properties": { "input": { "type": "string", "description": "An input into the tool" } },
"required": ["input"],
"additionalProperties": False,
"$schema": "http://json-schema.org/draft-07/schema#"
},
"strict": True
}],
"stream": False
}
r1 = requests.post(URL, headers=HEADERS, data=json.dumps(payload1))
r1.raise_for_status()
resp1 = r1.json()
# Extract the function_call item robustly (don’t assume output[0])
fc_item = next(i for i in resp1["output"] if i.get("type") == "function_call")
call_id = fc_item["call_id"]
# 2) Execute your tool
tool_output = "This is some output from our sample tool."
# 3) Second call – send only function_call_output + previous_response_id
payload2 = {
"model": MODEL,
"previous_response_id": resp1["id"],
"input": [{
"type": "function_call_output",
"call_id": call_id,
"status": "completed",
"output": tool_output
}],
"stream": False
}
r2 = requests.post(URL, headers=HEADERS, data=json.dumps(payload2))
r2.raise_for_status()
return r2.json()
Alternatively, manual replay of response.output can work when you can’t rely on server‑side state (e.g., certain retention policies), when you must send all prior output items, unmodified, in order, then immediately follow the function_call with your function_call_output. - Check the link above and this https://community.openai.com/t/issue-with-new-responses-api-400-no-tool-call-found-for-function-call-output-with-call-id/1142327 for more details.
I hope this is helpful! Do not hesitate to let me know if you have any other questions or clarifications.
Please don't forget to close up the thread here by upvoting and accept it as an answer if it is helpful.