OpenAI function calling JavaScript example
- Authors
- Name
- Hamza Rahman
- Published on
- -3 mins read
Use function calling when the model should choose a local function, pass structured arguments, and use the function result in its answer.
This example gives the model one tool: get_order_status.
Install
npm install openaiSet your API key:
export OPENAI_API_KEY="your_api_key_here"Code
import OpenAI from 'openai'
const openai = new OpenAI()
const tools = [ { type: 'function', name: 'get_order_status', description: 'Get the shipping status for an order ID.', parameters: { type: 'object', properties: { orderId: { type: 'string', description: 'The order ID, for example ORD-1001.', }, }, required: ['orderId'], additionalProperties: false, }, strict: true, },]
function getOrderStatus({ orderId }) { const orders = { 'ORD-1001': 'shipped', 'ORD-1002': 'processing', }
return { orderId, status: orders[orderId] || 'not_found', }}
function callFunction(name, args) { if (name === 'get_order_status') { return getOrderStatus(args) }
throw new Error(`Unknown tool: ${name}`)}
const input = [ { role: 'user', content: 'What is the status of order ORD-1001?', },]
const response = await openai.responses.create({ model: 'gpt-5.5', input, tools,})
for (const item of response.output) { if (item.type !== 'function_call') continue
const args = JSON.parse(item.arguments) const result = callFunction(item.name, args)
input.push(item) input.push({ type: 'function_call_output', call_id: item.call_id, output: JSON.stringify(result), })}
const finalResponse = await openai.responses.create({ model: 'gpt-5.5', input, tools,})
console.log(finalResponse.output_text)What is happening?
The first request lets the model decide whether to call get_order_status. Your code runs the tool locally, then sends the result back as function_call_output.
The second request lets the model turn that tool result into a normal answer.
Use this for
- Looking up database records
- Calling internal APIs
- Checking order, payment, or user status
- Letting an LLM choose from safe app actions
Common mistakes
- Sending the tool result back as a plain user message. It has to go back as a
function_call_outputwith the matchingcall_id, or the model cannot connect the result to its call. - Not looping. The model can request several tool calls, so handle every
function_callinresponse.output, not just the first one. - Skipping
strict: trueandadditionalProperties: false. Without them the model can invent extra arguments and your handler gets shapes you did not expect.
Related
- Vercel AI SDK tool calling example: the same idea with the tool loop handled for you.
- Force an LLM to return JSON in JavaScript: when you only need structured data back, not a function call.
References
Related articles
Force an LLM to return JSON in JavaScript
Reliably get JSON from an LLM in JavaScript with OpenAI structured outputs and a Zod schema, instead of prompting for JSON and parsing fragile model text yourself.
LangChain JS agent with a custom tool
Create a small LangChain JavaScript agent with one custom tool using createAgent, tool, and a Zod schema, with a runnable end-to-end example.
OpenAI structured outputs with Zod in JavaScript
Use OpenAI structured outputs with a Zod schema to get typed, app-ready JSON back from an LLM in JavaScript, with the schema doubling as your TypeScript types.

