Failed to create vector store - Unknown request URL: POST /v1/vector-stores

Hello everyone,

I’m currently working on a project involving the OpenAI Assistants v2 API, and I’m encountering issues since the switch from v1 to v2. My task is relatively straightforward:

  1. Upload a file (PDF).
  2. Run an assistant that applies a prompt to analyze the file.
  3. Extract structured data from the file and generate a PDF report with the results.

Here’s my current situation:

I’ve successfully implemented the file upload step.
I’m trying to create a vector store to enable the file_search tool in my assistant, but I’m encountering errors related to the API endpoint. Specifically, I receive the following response:
"Failed to create vector store: Unknown request URL: POST /v1/vector-stores. Please check the URL for typos, or see the docs at https://platform.openai.com/docs/api-reference/."

I’ve ensured the following:

  • I’m using the correct URL (https://api.openai.com/v1/vector-stores) as per the documentation.
  • I’ve included the required headers (OpenAI-Beta: assistants=v2).
  • My API key is correctly set and works for other endpoints.
 // Step 1: Upload the file
        $ch = curl_init("$baseUrl/files");
        $postFields = [
            'purpose' => 'assistants',
            'file' => new CURLFile($tempFile, $mimeType, "document.$fileExtension")
        ];
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $postFields,
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer $apiKey",
                "OpenAI-Beta: assistants=v2"
            ]
        ]);
        $uploadResponse = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        unlink($tempFile); // Delete temporary file

        $uploadResult = json_decode($uploadResponse, true);
        if ($httpCode !== 200 || !isset($uploadResult['id'])) {
            $errorMessage = $uploadResult['error']['message'] ?? 'Unknown error occurred';
            $this->sendError(ERROR_CANNOT_EXECUTE, "Failed to upload file: $errorMessage");
            return;
        }
        $fileId = $uploadResult['id'];
        
        // Step 2: Create a vector store for file_search
        $ch = curl_init("https://api.openai.com/v1/vector-stores");
        $vectorStoreData = json_encode([
            'files' => [$fileId], // Associe le fichier uploadé au vector store
            'purpose' => 'file_search',
        ]);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $vectorStoreData,
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer $apiKey",
                "Content-Type: application/json",
                "OpenAI-Beta: assistants=v2",
            ]
        ]);
        $vectorStoreResponse = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        $vectorStoreResult = json_decode($vectorStoreResponse, true);
        if ($httpCode !== 200 || !isset($vectorStoreResult['id'])) {
            $errorMessage = $vectorStoreResult['error']['message'] ?? 'Unknown error occurred';
            $this->sendError(ERROR_CANNOT_EXECUTE, "Failed to create vector store: $errorMessage");
            return;
        }
        $vectorStoreId = $vectorStoreResult['id']; // ID du vector store pour file_search

        // Step 3: Create an assistant
        $ch = curl_init("https://api.openai.com/v1/assistants");
        $assistantData = json_encode([
            'model' => 'gpt-4-turbo', // Modèle utilisé
            'name' => 'Document Analyzer', // Nom de l'assistant
            'instructions' => 'You are an AI assistant that analyzes documents.', // Instructions pour l'assistant
            'tools' => [
                ['type' => 'file_search'] // Déclare l'outil file_search
            ],
            'tool_resources' => [ // Associe les ressources au file_search
                'file_search' => [
                    'vector_store_ids' => [$vectorStoreId] // Utilise l'ID du vector store créé
                ]
            ]
        ]);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $assistantData,
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer $apiKey",
                "Content-Type: application/json",
                "OpenAI-Beta: assistants=v2"
            ]
        ]);
        $assistantResponse = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        $assistantResult = json_decode($assistantResponse, true);
        if ($httpCode !== 200 || !isset($assistantResult['id'])) {
            $errorMessage = $assistantResult['error']['message'] ?? 'Unknown error occurred';
            $this->sendError(ERROR_CANNOT_EXECUTE, "Failed to create assistant: $errorMessage");
            return;
        }
        $assistantId = $assistantResult['id']; // ID de l'assistant créé

        // Step 4: Create a thread
        $ch = curl_init("https://api.openai.com/v1/threads");
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode([]), // Pas besoin de paramètres pour cette étape
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer $apiKey",
                "Content-Type: application/json",
                "OpenAI-Beta: assistants=v2"
            ]
        ]);
        $threadResponse = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        $threadResult = json_decode($threadResponse, true);
        if ($httpCode !== 200 || !isset($threadResult['id'])) {
            $errorMessage = $threadResult['error']['message'] ?? 'Unknown error occurred';
            $this->sendError(ERROR_CANNOT_EXECUTE, "Failed to create thread: $errorMessage");
            return;
        }
        $threadId = $threadResult['id']; // ID du thread créé

        // Step 5: Add a message to the thread (avec fichier comme attachement)
        $ch = curl_init("$baseUrl/threads/$threadId/messages");
        $messageData = json_encode([
            'role' => 'user',
            'content' => $prompt,
            'attachments' => [
                [
                    'file_id' => $fileId,
                    'tools' => [['type' => 'file_search']]
                ]
            ]
        ]);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $messageData,
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer $apiKey",
                "Content-Type: application/json",
                "OpenAI-Beta: assistants=v2"
            ]
        ]);
        $messageResponse = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            $error = json_decode($messageResponse, true);
            $errorMessage = $error['error']['message'] ?? 'Unknown error occurred';
            $this->sendError(ERROR_CANNOT_EXECUTE, "Failed to add message: $errorMessage");
            return;
        }


        // Step 6: Run the assistant
        $ch = curl_init("https://api.openai.com/v1/threads/$threadId/runs");
        $runData = json_encode(['assistant_id' => $assistantId]);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $runData,
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer $apiKey",
                "Content-Type: application/json",
                "OpenAI-Beta: assistants=v2"
            ]
        ]);
        $runResponse = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        $runResult = json_decode($runResponse, true);
        if ($httpCode !== 200 || !isset($runResult['id'])) {
            $errorMessage = $runResult['error']['message'] ?? 'Unknown error occurred';
            $this->sendError(ERROR_CANNOT_EXECUTE, "Failed to run assistant: $errorMessage");
            return;
        }
        $runId = $runResult['id'];

        // Step 7: Wait for the run to complete
        do {
            sleep(5); // Wait for 5 seconds before checking again
            $ch = curl_init("https://api.openai.com/v1/threads/$threadId/runs/$runId");
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_HTTPHEADER => [
                    "Authorization: Bearer $apiKey",
                    "OpenAI-Beta: assistants=v2"
                ]
            ]);
            $statusResponse = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            if ($httpCode !== 200) {
                $error = json_decode($statusResponse, true);
                $errorMessage = $error['error']['message'] ?? 'Unknown error occurred';
                $this->sendError(ERROR_CANNOT_EXECUTE, "Failed to check run status: $errorMessage");
                return;
            }

            $statusResult = json_decode($statusResponse, true);
        } while ($statusResult['status'] === 'in_progress');

        // Step 8: Retrieve the assistant's response
        $ch = curl_init("https://api.openai.com/v1/threads/$threadId/messages");
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer $apiKey",
                "OpenAI-Beta: assistants=v2"
            ]
        ]);
        $messagesResponse = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            $error = json_decode($messagesResponse, true);
            $errorMessage = $error['error']['message'] ?? 'Unknown error occurred';
            $this->sendError(ERROR_CANNOT_EXECUTE, "Failed to retrieve messages: $errorMessage");
            return;
        }

        $messagesResult = json_decode($messagesResponse, true);
        $assistantReply = $messagesResult['data'][0]['content'][0]['text']['value'] ?? '';

        return $assistantReply;     
    }

That code always end with this error : “Failed to create vector store: Unknown request URL: POST /v1/vector-stores. Please check the URL for typos, or see the docs at https://platform.openai.com/docs/api-reference/.

Is there anything else I might be missing in my implementation or API setup?

Any guidance would be greatly appreciated. Thank you in advance!