OpenAI API key with “proj-” prefix not working when read from .env file

I’m working on a Next.js/React/TypeScript project that integrates with the OpenAI API. I’ve encountered an issue with the new Project-based API keys feature.
Previously, I successfully used this setup:

typescriptCopyconst openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY, });

My .env file contained:

OPENAI_API_KEY=sk-xxxxx

However, with the new Project-based API keys (format: sk-proj-xxxxx), this setup no longer works. I’m receiving an invalid_api_key error.

I’ve noticed that process.env.OPENAI_API_KEY seems to strip the proj- part from the API key when reading it from the .env file.

Oddly enough, using the key as a plain string works fine:
const openai = new OpenAI({ apiKey: "sk-proj-xxxxx", });

I’ve scoured the OpenAI documentation and googled the hell out of it but haven’t found any solutions. The closest relevant information I found was in the OpenAI Authentication documentation.

Has anyone encountered this problem? Any insights or solutions would be greatly appreciated! 🙂

My route.ts:

import { auth } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
import OpenAI from "openai";

const openai = new OpenAI({
  apiKey: "process.env.OPENAI_API_KEY", //this seems to be the issue
});

const instructionMessage = {
  role: "system",
  content: `blah blah instructions`,
};

async function POST(req: Request) {
  try {
    const { userId } = auth();
    const body = await req.json();
    const { messages } = body;
    const lastMessage = messages[messages.length - 1];

    if (!userId) {
      return new NextResponse("Unauthorized", { status: 401 });
    }

    if (!openai.apiKey) {
      return new NextResponse("OpenAi Api Key not configured"), { status: 500 };
    }

    if (!messages || messages.length === 0) {
      return new NextResponse("Input Required", { status: 400 });
    }

    const response = await openai.chat.completions.create({
      model: "gpt-4o-mini",
      messages: [instructionMessage, lastMessage],
    });

    return NextResponse.json(response.choices[0].message);
  } catch (error) {
    console.log("[CODE_ERROR]", error);
    return new NextResponse("Internal error", { status: 500 });
  }
}

export { POST };