April 18, 2025
OpenAI Responses API for TypeScript Developers
A simple overview of how to use the OpenAI Responses API with TypeScript, including setup, streaming responses, and managing conversation state without a database.
By Ross Robinogpt / openai / responses
OpenAI released a new Responses API in March 2025. The Responses API is the successor to the Chat Completions API, and is the standard way to interact with OpenAI’s LLMs. Check out OpenAI’s comparison of the two APIs to understand the main differences between the two.
Here’s how you can utilize the new API in a TypeScript server application.
I’m going to use the domco Vite plugin for this project, but you can use any popular JS server framework.
Install the openai package, I’m going to use dotenv to manage environment variables. If you are using a different framework, environment variable setup might be done for you, so be sure to review the framework’s documentation. I’m also using zod to validate form inputs.
Create an API key and add it to a .env file in your root directory.
Be sure .env is included in your .gitignore file as well so you do not commit secret information to your repository.
Lets add a <form> to our HTML page to submit a message to our API, and a <div> element to put the response from the assistant into.
We’ll also add a <script> tag pointing to /client/main.ts to add some client side JavaScript that will handle our form submission.
In main.ts, add an event listener to the form that will execute on the submit event. We’ll handle the submission with JavaScript so we can easily stream the assistant’s response into the page.
Now if we submit our form, given the /chat action, we should see a 404 message in the console and our nope message in the response. We need to add a new /chat route on the backend to handle this request.
First, let’s get the message from the form from req.formData. We can just return the message as text to start with.
Now when the form is submitted, the same message should be rendered below.
To generate a response using the Responses API, create an src/server/ai.ts module, import the OpenAI client, and provide your API key.
Now we can import this module and use the client to create an AI response.
Send the response.output_text back as our response. You’ve now created a simple chat application with the Responses API!
Instead of waiting for the entire message to buffer on the server before sending it back we can stream the response to the client as it comes in to give the user a faster response.
Add the stream: true property to the responses.create argument.
Now the response is an AsyncIterable stream, so we can iterate through each ResponseStreamEvent to send the data as it streams in.
Create a new ReadableStream body to handle the stream.
The ResponseStreamEvent has a type property that distinguishes what kind of event is being sent. The "response.output_text.delta" type is the one we are looking for. It contains the change in the output text since the last event in the delta property.
Now we can pass this stream into our Response constructor to stream the contents from our /chat route on the fly.
OpenAI makes it possible to retrieve previous messages from the same conversation using an ID. This is nice because you do not have to send any of the previous messages when you are having a multi-message conversation, or store anything in a database of your own.
Obtain the id from the FormData, pass it into the previous_response_id property.
Set store: true to instruct OpenAI to store the conversation.
To obtain the id from the response when streaming, it is contained in the "response.completed" event instead of directly on the response object. Let’s send this id to the client at the end of the stream.
Then when the form is submitted again it will contain the id within the FormData.
Now the assistant will remember the previous messages.
When using reasoning models like GPT-5, add the reasoning option when creating a response to obtain a summary of the reasoning and set the effort. A higher effort might give a better response, but it will take longer and use more tokens (cost more).
The full reasoning summary is contained in the response.reasoning_summary_text.done event.
In the case you need to get the previous messages in a conversation, you’ll need to make two requests.
The Responses API provides a nice way to interact with OpenAI’s LLMs. The final project is located on GitHub. Thanks for reading!…