New to the Responses API (C#) and having trouble performing both an upload and returning structured output

I’m trying to do something I thought would take me 10 minutes to get working, but I keep hitting walls even with ChatGPT’s help as the examples it generates don’t work.

using OpenAI.Assistants;
using OpenAI.Chat;
using OpenAI.Files;
using OpenAI.Responses;
using OpenAI.VectorStores;

var prompt = "Summarize this document using a single paragraph";
var testKey = "<insert_key>";
var model = "gpt-5";
var filenameAndPath = "./TestFiles/document.pdf";
var filename = Path.GetFileName(filenameAndPath);
var api = new OpenAI.OpenAIClient(testKey);
var client = api.GetChatClient(model);
var files = api.GetOpenAIFileClient();
var vectors = api.GetVectorStoreClient();
using var stream = File.OpenRead(filenameAndPath);

// upload the file
var uploaded = await files.UploadFileAsync(stream, filename, FileUploadPurpose.Assistants);
var store = await vectors.CreateVectorStoreAsync(true, new VectorStoreCreationOptions { Name = "spec-store" });
await vectors.AddFileToVectorStoreAsync(store.VectorStoreId, uploaded.Value.Id, true);

// do the work
var responses = api.GetOpenAIResponseClient(model);
var tool = ResponseTool.CreateFileSearchTool(vectorStoreIds: [store.Value.Id]);
var response = await responses.CreateResponseAsync(
    userInputText: prompt,
    new ResponseCreationOptions
    {
        Tools = { tool }
    }
);

There doesn’t appear to be a way to provide the ChatCompletionOptions required to set the json schema when using the Responses API:

var options = new ChatCompletionOptions
{
    ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(
        "Device",
        schema,
        "You must respond in valid json that can be deserialized into the Device object. Do not include any other text outside of the json object.",
        jsonSchemaIsStrict: true)
};

I asked ChatGPT how to provide it or something like it to the Responses api and it referred me to going down the raw request route using the “protocol method” in order to perform both functions. However, that just lead to the api giving me the response “unknown_parameter ‘tool_resources’“ and I suspect surely there is a way to do this in the standard api.

Here is your destination, the cs code class sending the “text.format” parameter that contains the schema within a special container (no longer a response_format parameter behind the scenes):

CreateJsonSchemaFormat(...)

It seems the other aspect you need is:

  • uploading a file to storage (use purpose “user_data” now that assistants is a passe name)
  • creating a vector store (no longer beta)
  • attaching the file IDs to the vector store
  • using the internal tool for file_search with the vector store name when you make an Responses API call

The API reference at least gives you that parameter’s creation:

using System;

using OpenAI.Responses;

OpenAIResponseClient client = new(
    model: "gpt-4.1",
    apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY")
);

string userInputText = "What are the attributes of an ancient brown dragon?";

ResponseCreationOptions options = new()
{
    Tools =
    {
        ResponseTool.CreateFileSearchTool(
            vectorStoreIds: ["vs_1234567890"],
            maxResultCount: 20
        )
    },
};

OpenAIResponse response = client.CreateResponse(userInputText, options);

Console.WriteLine(response.GetOutputText());