How to rework a full payload based api call to a streamed call?

I have the following API call which correctly sends a query, waits for the entire response before passing back to an ajax call. But I want to the API call to instead begin returning back the response in real-time, just like how chatGPT streams the response. I understand that the the stream mode needs to be set to true ( stream => true), however I am going around in circles trying to send each received token from the response and handle it in my ajax call to update an html element in real time.

Any help, advice, example code would be incredible and i’m sure help many others out there.

function ask_question() {
  $query = $_POST['query'];
  $query_credit = $_POST['queryCredit'];
  $user_id = get_current_user_id();
  $meta_key = 'ai_anna_credit';
  $user_credit = get_user_meta( $user_id, $meta_key, true);
  if ($user_credit <= 0) {
    $response = 'You do not have enough credit for this aiAnna question.';
  } else {
    $ch = curl_init();
    $url = '';
    $api_key = 'sk-******************************************';
    $post_fields = array(
      'model' => 'gpt-3.5-turbo',
      'messages' => array(
          'role' => 'system',
          'content' => 'You are aiAnna, a helpful virtual teacher's assistant!'
          'role' => 'user',
          'content' => $query

    $header = array(
      'Content-Type: application/json',
      'Authorization: Bearer ' . $api_key

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_fields));
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

    $result = curl_exec($ch);
    if (curl_errno($ch)) {
      $response = 'Error: ' . curl_error($ch);
	} else {
      $response_data = json_decode($result);
      $response = $response_data->choices[0]->message->content;
	  if (!empty($response)) {
        $new_credit = $user_credit - $query_credit;
        update_user_meta( $user_id, $meta_key, $new_credit);
        $user_credit = get_user_meta( $user_id, $meta_key, true);
  $response_data = array(
    'response' => $response,
    'user_credit' => $user_credit

This might be your problem. I haven’t tested…

header("Content-Type: text/event-stream");

Hope this helps!