HTTP Response Code 400 in Java

Hi all,
I’m trying to write some code to use OpenAI API in Java (this is my first time) but I still receive the following error:

Exception in thread “main” java.io.IOException: Server returned HTTP response code: 400 for URL: h t t p s : / / a p i . o p e n a i . c o m / v 1 / completions
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1894)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
at com.example.solrplugin.ChatGPT.chatGPT(ChatGPT.java:43)
at com.example.solrplugin.ChatGPT.main(ChatGPT.java:56)

This is my code:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.JSONArray;
import org.json.JSONObject;

public class ChatGPT {
    public static void chatGPT(String text) throws Exception {
        String url = "https://api.openai.com/v1/completions";
        HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();

        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json");
        con.setRequestProperty("Authorization", "Bearer MY-API-KEY");

        String model = "gpt-3.5-turbo";
        JSONArray messages = new JSONArray();
        JSONObject userMessage = new JSONObject();
        userMessage.put("role", "user");
        userMessage.put("content", text);
        messages.put(userMessage);

        int maxTokens = 4096;

        con.setDoOutput(true);

        System.out.println(con);

        JSONObject requestBody = new JSONObject();
        requestBody.put("model", model);
        requestBody.put("messages", messages);
        requestBody.put("max_tokens", maxTokens);

        OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
        writer.write(requestBody.toString());
        writer.flush();

        // Leggi la risposta
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuilder response = new StringBuilder();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }

        in.close();

        System.out.println(response.toString());
    }

    public static void main(String[] args) throws Exception {
        chatGPT("Hello, how are you?");
    }
}

Can you help me to solve this problem? Thanks in advance :smiley:

Welcome to the forum!

You need to run the API call part of your js app from outside of the browser to avoid CORS violations, i.e. run a Node app on a server like this:

(Note the serves both completion requests and web pages from the /public/ folder of your project, and uses the API key stored in your local environment variables, you can create a new variable with export OPENAI_API_KEY=your_api_key_here, you can also add that to your .bashrc config file to ensure it is retained across sessions)

You can then put your html in the public folder and have it call this server like this from your web page:

<script>
    async function testAPI() {
        const model = document.getElementById('model').value;
        const messages = [
            {role: "system", content: "You are a helpful assistant."},
            {role: "user", content: document.getElementById('message').value}
        ];
        const response = await fetch('/api/completion', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({model: model, messages: messages})
        });
        const data = await response.json();
        document.getElementById('response').innerText = JSON.stringify(data, null, 2);
    }

    window.onload = function() {
        document.getElementById('model').value = 'gpt-3.5-turbo';
        document.getElementById('message').value = 'Translate the following English text to French: "Hello, world!"';
        testAPI();
    }
</script>
const express = require('express');
const { Configuration, OpenAIApi } = require('openai');
const app = express();
const port = 5000;

// Set up the API configuration
const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

// Serve static files from the "public" folder
app.use(express.static('public'));

app.use(express.json());

app.post('/api/completion', async (req, res) => {
  const { model, messages } = req.body;

  try {
    const completion = await openai.createChatCompletion({
      model: model,
      messages: messages,
    });
    res.json(completion.data.choices[0].message);
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: 'An error occurred while processing the request.' });
  }
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

Thanks for the answer but I’m trying to build a Java app, not JavaScript.

Ahh, OK.

Well maybe of relevance, in my c++ api calling implantation I had to split the address up like this

 const char* _apiKey;
 const char* _apiDomain = "api.openai.com";
 const char* _apiPath = "/v1/chat/completions";

and then build them back up like this

String payload;
    String authorizationHeader = "";
    serializeJson(root, payload);
    authorizationHeader = "Authorization: Bearer " + String(_apiKey);
    _client.println("POST " + String(_apiPath) + " HTTP/1.1");
    _client.println("Host: " + String(_apiDomain));
    _client.println("Content-Type: application/json");
    _client.println(authorizationHeader);
    _client.println("Content-Length: " + String(payload.length()));
    _client.println();
    _client.print(payload);

As I was getting errors. Not sure how applicable that is here. the + HTTP/1.1 bit needed to be inserted for mine to work.

The endpoint should be chat/completions not just completions (legacy models)

You also need to set stream to true if you want to stream the response

4 Likes

Yup, that will do it! Good catch. the little /chat/ bit is a common failure mode.

1 Like

Thanks a lot, it worked like charme :smiley: